Mercurial > emacs
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 |