comparison src/gtkutil.c @ 92366:39b38c867ca4

(xg_resize_outer_widget): Only do one of set_geometry or set_char_size. (xg_frame_resized): Renamed from xg_resize_widgets. Remove all operations on widgets here. Just set frame size if needed. (flush_and_sync, x_wm_size_hint_off, xg_pack_tool_bar): New functions. (xg_frame_set_char_size): Call x_wm_size_hint_off before resizing. (x_wm_set_size_hint): Set size hints on the edit widget only, not the whole frame. (xg_create_tool_bar): Move attachement of the tool bar to xg_pack_tool_bar. Do not attach the tool bar if there are no items. (free_frame_tool_bar): Remove call to SET_FRAME_GARBAGED.
author Jan Djärv <jan.h.d@swipnet.se>
date Sat, 01 Mar 2008 14:56:53 +0000
parents 370f67c176eb
children d38f7962c052
comparison
equal deleted inserted replaced
92365:da14af9c4d86 92366:39b38c867ca4
643 { 643 {
644 /* If we are not mapped yet, set geometry once again, as window 644 /* If we are not mapped yet, set geometry once again, as window
645 height now have changed. */ 645 height now have changed. */
646 if (! GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f))) 646 if (! GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
647 xg_set_geometry (f); 647 xg_set_geometry (f);
648 648 else
649 xg_frame_set_char_size (f, columns, rows); 649 xg_frame_set_char_size (f, columns, rows);
650 gdk_window_process_all_updates (); 650 }
651 } 651
652 652 /* Function to handle resize of our frame. As we have a Gtk+ tool bar
653 /* Function to handle resize of our widgets. Since Emacs has some layouts 653 and a Gtk+ menu bar, we get resize events for the edit part of the
654 that does not fit well with GTK standard containers, we do most layout 654 frame only. We let Gtk+ deal with the Gtk+ parts.
655 manually.
656 F is the frame to resize. 655 F is the frame to resize.
657 PIXELWIDTH, PIXELHEIGHT is the new size in pixels. */ 656 PIXELWIDTH, PIXELHEIGHT is the new size in pixels. */
658 657
659 void 658 void
660 xg_resize_widgets (f, pixelwidth, pixelheight) 659 xg_frame_resized (f, pixelwidth, pixelheight)
661 FRAME_PTR f; 660 FRAME_PTR f;
662 int pixelwidth, pixelheight; 661 int pixelwidth, pixelheight;
663 { 662 {
664 int mbheight = FRAME_MENUBAR_HEIGHT (f); 663 int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
665 int tbheight = FRAME_TOOLBAR_HEIGHT (f);
666 int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (pixelheight
667 - mbheight - tbheight));
668 int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth); 664 int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
669 665
670 if (FRAME_GTK_WIDGET (f) 666 if (FRAME_GTK_WIDGET (f)
671 && (columns != FRAME_COLS (f) 667 && (columns != FRAME_COLS (f)
672 || rows != FRAME_LINES (f) 668 || rows != FRAME_LINES (f)
673 || pixelwidth != FRAME_PIXEL_WIDTH (f) 669 || pixelwidth != FRAME_PIXEL_WIDTH (f)
674 || pixelheight != FRAME_PIXEL_HEIGHT (f))) 670 || pixelheight != FRAME_PIXEL_HEIGHT (f)))
675 { 671 {
676 struct x_output *x = f->output_data.x; 672 FRAME_PIXEL_WIDTH (f) = pixelwidth;
677 GtkAllocation all; 673 FRAME_PIXEL_HEIGHT (f) = pixelheight;
678 674
679 all.y = mbheight + tbheight; 675 if (rows != FRAME_LINES (f) || columns != FRAME_COLS (f)
680 all.x = 0; 676 || (f->new_text_lines != 0 && f->new_text_lines != rows)
681 677 || (f->new_text_cols != 0 && f->new_text_cols != columns))
682 all.width = pixelwidth; 678 {
683 all.height = pixelheight - mbheight - tbheight; 679 change_frame_size (f, rows, columns, 0, 1, 0);
684 680 SET_FRAME_GARBAGED (f);
685 gtk_widget_size_allocate (x->edit_widget, &all); 681 cancel_mouse_face (f);
686 682 }
687 change_frame_size (f, rows, columns, 0, 1, 0); 683 }
688 SET_FRAME_GARBAGED (f); 684 }
689 cancel_mouse_face (f); 685
690 } 686 /* Process all pending events on the display for frame F. */
691 } 687
692 688 static void
689 flush_and_sync (f)
690 FRAME_PTR f;
691 {
692 gdk_window_process_all_updates ();
693 x_sync (f);
694 while (gtk_events_pending ())
695 {
696 gtk_main_iteration ();
697 gdk_window_process_all_updates ();
698 x_sync (f);
699 }
700 }
701
702 /* Turn wm hints for resize off on frame F */
703
704 static void
705 x_wm_size_hint_off (f)
706 FRAME_PTR f;
707 {
708 GdkGeometry size_hints;
709 gint hint_flags = 0;
710 memset (&size_hints, 0, sizeof (size_hints));
711 hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE;
712 size_hints.width_inc = 1;
713 size_hints.height_inc = 1;
714 hint_flags |= GDK_HINT_BASE_SIZE;
715 size_hints.base_width = 1;
716 size_hints.base_height = 1;
717 size_hints.min_width = 1;
718 size_hints.min_height = 1;
719 gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
720 FRAME_GTK_WIDGET (f),
721 &size_hints,
722 hint_flags);
723 /* Make sure these get set again in next call to x_wm_set_size_hint. */
724 f->output_data.x->hint_flags &= ~hint_flags;
725 flush_and_sync (f);
726 }
693 727
694 /* Update our widget size to be COLS/ROWS characters for frame F. */ 728 /* Update our widget size to be COLS/ROWS characters for frame F. */
695 729
696 void 730 void
697 xg_frame_set_char_size (f, cols, rows) 731 xg_frame_set_char_size (f, cols, rows)
700 int rows; 734 int rows;
701 { 735 {
702 int pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows) 736 int pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows)
703 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); 737 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
704 int pixelwidth; 738 int pixelwidth;
739
740 if (FRAME_PIXEL_HEIGHT (f) == 0)
741 return;
705 742
706 /* Take into account the size of the scroll bar. Always use the 743 /* Take into account the size of the scroll bar. Always use the
707 number of columns occupied by the scroll bar here otherwise we 744 number of columns occupied by the scroll bar here otherwise we
708 might end up with a frame width that is not a multiple of the 745 might end up with a frame width that is not a multiple of the
709 frame's character width which is bad for vertically split 746 frame's character width which is bad for vertically split
715 752
716 /* FRAME_TEXT_COLS_TO_PIXEL_WIDTH uses scroll_bar_actual_width, so call it 753 /* FRAME_TEXT_COLS_TO_PIXEL_WIDTH uses scroll_bar_actual_width, so call it
717 after calculating that value. */ 754 after calculating that value. */
718 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); 755 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
719 756
757
720 /* Must resize our top level widget. Font size may have changed, 758 /* Must resize our top level widget. Font size may have changed,
721 but not rows/cols. */ 759 but not rows/cols.
760 Turn wm hints (min/max size and size increments) of temporarly.
761 It interferes too much, when for example adding or removing the
762 menu/tool bar. */
763 x_wm_size_hint_off (f);
722 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 764 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
723 pixelwidth, pixelheight); 765 pixelwidth, pixelheight);
724 xg_resize_widgets (f, pixelwidth, pixelheight);
725 x_wm_set_size_hint (f, 0, 0); 766 x_wm_set_size_hint (f, 0, 0);
726 SET_FRAME_GARBAGED (f);
727 cancel_mouse_face (f);
728 } 767 }
729 768
730 /* Convert an X Window WSESC on display DPY to its corresponding GtkWidget. 769 /* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
731 Must be done like this, because GtkWidget:s can have "hidden" 770 Must be done like this, because GtkWidget:s can have "hidden"
732 X Window that aren't accessible. 771 X Window that aren't accessible.
829 gtk_container_add (GTK_CONTAINER (wtop), wvbox); 868 gtk_container_add (GTK_CONTAINER (wtop), wvbox);
830 gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0); 869 gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
831 870
832 if (FRAME_EXTERNAL_TOOL_BAR (f)) 871 if (FRAME_EXTERNAL_TOOL_BAR (f))
833 update_frame_tool_bar (f); 872 update_frame_tool_bar (f);
834
835 /* The tool bar is created but first there are no items in it.
836 This causes it to be zero height. Later items are added, but then
837 the frame is already mapped, so there is a "jumping" resize.
838 This makes geometry handling difficult, for example -0-0 will end
839 up in the wrong place as tool bar height has not been taken into account.
840 So we cheat a bit by setting a height that is what it will have
841 later on when tool bar items are added. */
842 if (FRAME_EXTERNAL_TOOL_BAR (f) && f->n_tool_bar_items == 0)
843 FRAME_TOOLBAR_HEIGHT (f) = 38;
844
845 873
846 /* We don't want this widget double buffered, because we draw on it 874 /* We don't want this widget double buffered, because we draw on it
847 with regular X drawing primitives, so from a GTK/GDK point of 875 with regular X drawing primitives, so from a GTK/GDK point of
848 view, the widget is totally blank. When an expose comes, this 876 view, the widget is totally blank. When an expose comes, this
849 will make the widget blank, and then Emacs redraws it. This flickers 877 will make the widget blank, and then Emacs redraws it. This flickers
945 size_hints.width_inc = FRAME_COLUMN_WIDTH (f); 973 size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
946 size_hints.height_inc = FRAME_LINE_HEIGHT (f); 974 size_hints.height_inc = FRAME_LINE_HEIGHT (f);
947 975
948 hint_flags |= GDK_HINT_BASE_SIZE; 976 hint_flags |= GDK_HINT_BASE_SIZE;
949 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); 977 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
950 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0) 978 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
951 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
952 979
953 check_frame_size (f, &min_rows, &min_cols); 980 check_frame_size (f, &min_rows, &min_cols);
954 981
955 size_hints.base_width = base_width; 982 size_hints.base_width = base_width;
956 size_hints.base_height = base_height; 983 size_hints.base_height = base_height;
991 { 1018 {
992 hint_flags &= ~GDK_HINT_POS; 1019 hint_flags &= ~GDK_HINT_POS;
993 hint_flags |= GDK_HINT_USER_POS; 1020 hint_flags |= GDK_HINT_USER_POS;
994 } 1021 }
995 1022
996 BLOCK_INPUT; 1023 if (hint_flags != f->output_data.x->hint_flags
997 1024 || memcmp (&size_hints,
998 gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1025 &f->output_data.x->size_hints,
999 FRAME_GTK_OUTER_WIDGET (f), 1026 sizeof (size_hints)) != 0)
1000 &size_hints, 1027 {
1001 hint_flags); 1028 BLOCK_INPUT;
1002 1029
1003 f->output_data.x->size_hints = size_hints; 1030 gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1004 f->output_data.x->hint_flags = hint_flags; 1031 FRAME_GTK_WIDGET (f),
1005 UNBLOCK_INPUT; 1032 &size_hints,
1033 hint_flags);
1034
1035 f->output_data.x->size_hints = size_hints;
1036 f->output_data.x->hint_flags = hint_flags;
1037 UNBLOCK_INPUT;
1038 }
1006 } 1039 }
1007 } 1040 }
1008 1041
1009 /* Change background color of a frame. 1042 /* Change background color of a frame.
1010 Since GTK uses the background colour to clear the window, we must 1043 Since GTK uses the background colour to clear the window, we must
3666 event->area.height = max (height, event->area.height); 3699 event->area.height = max (height, event->area.height);
3667 3700
3668 return FALSE; 3701 return FALSE;
3669 } 3702 }
3670 3703
3671 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX)) 3704 /* Attach a tool bar to frame F. */
3672 3705
3706 static void
3707 xg_pack_tool_bar (f)
3708 FRAME_PTR f;
3709 {
3710 struct x_output *x = f->output_data.x;
3711 int vbox_pos = x->menubar_widget ? 1 : 0;
3712
3713 x->handlebox_widget = gtk_handle_box_new ();
3714 g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached",
3715 G_CALLBACK (xg_tool_bar_detach_callback), f);
3716 g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached",
3717 G_CALLBACK (xg_tool_bar_attach_callback), f);
3718
3719 gtk_container_add (GTK_CONTAINER (x->handlebox_widget),
3720 x->toolbar_widget);
3721
3722 gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget,
3723 FALSE, FALSE, 0);
3724
3725 gtk_box_reorder_child (GTK_BOX (x->vbox_widget), x->handlebox_widget,
3726 vbox_pos);
3727 gtk_widget_show_all (x->handlebox_widget);
3728 }
3673 3729
3674 /* Create a tool bar for frame F. */ 3730 /* Create a tool bar for frame F. */
3675 3731
3676 static void 3732 static void
3677 xg_create_tool_bar (f) 3733 xg_create_tool_bar (f)
3678 FRAME_PTR f; 3734 FRAME_PTR f;
3679 { 3735 {
3680 struct x_output *x = f->output_data.x; 3736 struct x_output *x = f->output_data.x;
3681 GtkRequisition req; 3737 GtkRequisition req;
3682 int vbox_pos = x->menubar_widget ? 1 : 0;
3683 3738
3684 x->toolbar_widget = gtk_toolbar_new (); 3739 x->toolbar_widget = gtk_toolbar_new ();
3685 x->handlebox_widget = gtk_handle_box_new ();
3686 x->toolbar_detached = 0; 3740 x->toolbar_detached = 0;
3687
3688 gtk_container_add (GTK_CONTAINER (x->handlebox_widget),
3689 x->toolbar_widget);
3690
3691 gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget,
3692 FALSE, FALSE, 0);
3693
3694 gtk_box_reorder_child (GTK_BOX (x->vbox_widget), x->handlebox_widget,
3695 vbox_pos);
3696 3741
3697 gtk_widget_set_name (x->toolbar_widget, "emacs-toolbar"); 3742 gtk_widget_set_name (x->toolbar_widget, "emacs-toolbar");
3698 3743
3699 /* We only have icons, so override any user setting. We could 3744 /* We only have icons, so override any user setting. We could
3700 use the caption property of the toolbar item (see update_frame_tool_bar 3745 use the caption property of the toolbar item (see update_frame_tool_bar
3704 tool bar item. I think the creators of the GtkToolbar widget 3749 tool bar item. I think the creators of the GtkToolbar widget
3705 counted on 4 or 5 character long strings. */ 3750 counted on 4 or 5 character long strings. */
3706 gtk_toolbar_set_style (GTK_TOOLBAR (x->toolbar_widget), GTK_TOOLBAR_ICONS); 3751 gtk_toolbar_set_style (GTK_TOOLBAR (x->toolbar_widget), GTK_TOOLBAR_ICONS);
3707 gtk_toolbar_set_orientation (GTK_TOOLBAR (x->toolbar_widget), 3752 gtk_toolbar_set_orientation (GTK_TOOLBAR (x->toolbar_widget),
3708 GTK_ORIENTATION_HORIZONTAL); 3753 GTK_ORIENTATION_HORIZONTAL);
3709 3754 }
3710 g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached", 3755
3711 G_CALLBACK (xg_tool_bar_detach_callback), f); 3756
3712 g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached", 3757 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
3713 G_CALLBACK (xg_tool_bar_attach_callback), f);
3714
3715 gtk_widget_show_all (x->handlebox_widget);
3716
3717 gtk_widget_size_request (x->toolbar_widget, &req);
3718 FRAME_TOOLBAR_HEIGHT (f) = req.height;
3719
3720 /* The height has changed, resize outer widget and set columns
3721 rows to what we had before adding the tool bar. */
3722 xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f));
3723
3724 SET_FRAME_GARBAGED (f);
3725 }
3726 3758
3727 /* Find the right-to-left image named by RTL in the tool bar images for F. 3759 /* Find the right-to-left image named by RTL in the tool bar images for F.
3728 Returns IMAGE if RTL is not found. */ 3760 Returns IMAGE if RTL is not found. */
3729 3761
3730 static Lisp_Object 3762 static Lisp_Object
3769 struct x_output *x = f->output_data.x; 3801 struct x_output *x = f->output_data.x;
3770 int hmargin = 0, vmargin = 0; 3802 int hmargin = 0, vmargin = 0;
3771 GtkToolbar *wtoolbar; 3803 GtkToolbar *wtoolbar;
3772 GtkToolItem *ti; 3804 GtkToolItem *ti;
3773 GtkTextDirection dir; 3805 GtkTextDirection dir;
3806 int pack_tool_bar = x->handlebox_widget == NULL;
3774 3807
3775 if (! FRAME_GTK_WIDGET (f)) 3808 if (! FRAME_GTK_WIDGET (f))
3776 return; 3809 return;
3777 3810
3778 BLOCK_INPUT; 3811 BLOCK_INPUT;
4075 { 4108 {
4076 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i++); 4109 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i++);
4077 if (ti) gtk_widget_hide_all (GTK_WIDGET (ti)); 4110 if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
4078 } while (ti != NULL); 4111 } while (ti != NULL);
4079 4112
4113 new_req.height = 0;
4080 gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req); 4114 gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req);
4081 if (old_req.height != new_req.height 4115
4116 if (pack_tool_bar && f->n_tool_bar_items != 0)
4117 xg_pack_tool_bar (f);
4118
4119 if (new_req.height != 0
4120 && f->n_tool_bar_items != 0
4121 && old_req.height != new_req.height
4082 && ! FRAME_X_OUTPUT (f)->toolbar_detached) 4122 && ! FRAME_X_OUTPUT (f)->toolbar_detached)
4083 { 4123 {
4084 FRAME_TOOLBAR_HEIGHT (f) = new_req.height; 4124 FRAME_TOOLBAR_HEIGHT (f) = new_req.height;
4085 xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f)); 4125 xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f));
4086 } 4126 }
4107 FRAME_TOOLBAR_HEIGHT (f) = 0; 4147 FRAME_TOOLBAR_HEIGHT (f) = 0;
4108 4148
4109 /* The height has changed, resize outer widget and set columns 4149 /* The height has changed, resize outer widget and set columns
4110 rows to what we had before removing the tool bar. */ 4150 rows to what we had before removing the tool bar. */
4111 xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f)); 4151 xg_resize_outer_widget (f, FRAME_COLS (f), FRAME_LINES (f));
4112
4113 SET_FRAME_GARBAGED (f);
4114 UNBLOCK_INPUT; 4152 UNBLOCK_INPUT;
4115 } 4153 }
4116 } 4154 }
4117 4155
4118 4156