Mercurial > emacs
comparison src/gtkutil.c @ 57597:754a6433f048
* gtkutil.c (xg_frame_cleared, xg_fixed_handle_expose,
xg_find_top_left_in_fixed): Removed.
(xg_create_scroll_bar): Put an event box widget between
the scroll bar widget and the edit widget.
(xg_show_scroll_bar): Show the parent widget (the event box).
(xg_remove_scroll_bar): Destroy parent (the event box) also.
(xg_update_scrollbar_pos): Remove arguments real_left and canon_width.
Move the parent (the event box) widget inside the fixed widget.
Move window clear to xterm.c.
author | Jan Djärv <jan.h.d@swipnet.se> |
---|---|
date | Tue, 19 Oct 2004 16:40:03 +0000 |
parents | da44dbb5ee89 |
children | cdc48cdd5b0e f3ec05478165 |
comparison
equal
deleted
inserted
replaced
57596:94778fc7dc76 | 57597:754a6433f048 |
---|---|
548 | 548 |
549 xg_frame_set_char_size (f, columns, rows); | 549 xg_frame_set_char_size (f, columns, rows); |
550 gdk_window_process_all_updates (); | 550 gdk_window_process_all_updates (); |
551 } | 551 } |
552 | 552 |
553 /* This gets called after the frame F has been cleared. Since that is | |
554 done with X calls, we need to redraw GTK widget (scroll bars). */ | |
555 void | |
556 xg_frame_cleared (f) | |
557 FRAME_PTR f; | |
558 { | |
559 GtkWidget *w = f->output_data.x->widget; | |
560 | |
561 if (w) | |
562 { | |
563 gtk_container_set_reallocate_redraws (GTK_CONTAINER (w), TRUE); | |
564 gtk_container_foreach (GTK_CONTAINER (w), | |
565 (GtkCallback) gtk_widget_queue_draw, | |
566 0); | |
567 gdk_window_process_all_updates (); | |
568 } | |
569 } | |
570 | |
571 /* Function to handle resize of our widgets. Since Emacs has some layouts | 553 /* Function to handle resize of our widgets. Since Emacs has some layouts |
572 that does not fit well with GTK standard containers, we do most layout | 554 that does not fit well with GTK standard containers, we do most layout |
573 manually. | 555 manually. |
574 F is the frame to resize. | 556 F is the frame to resize. |
575 PIXELWIDTH, PIXELHEIGHT is the new size in pixels. */ | 557 PIXELWIDTH, PIXELHEIGHT is the new size in pixels. */ |
583 int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (pixelheight | 565 int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (pixelheight |
584 - mbheight - tbheight)); | 566 - mbheight - tbheight)); |
585 int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth); | 567 int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth); |
586 | 568 |
587 if (FRAME_GTK_WIDGET (f) | 569 if (FRAME_GTK_WIDGET (f) |
588 && (columns != FRAME_COLS (f) || rows != FRAME_LINES (f) | 570 && (columns != FRAME_COLS (f) |
589 || pixelwidth != FRAME_PIXEL_WIDTH (f) || pixelheight != FRAME_PIXEL_HEIGHT (f))) | 571 || rows != FRAME_LINES (f) |
572 || pixelwidth != FRAME_PIXEL_WIDTH (f) | |
573 || pixelheight != FRAME_PIXEL_HEIGHT (f))) | |
590 { | 574 { |
591 struct x_output *x = f->output_data.x; | 575 struct x_output *x = f->output_data.x; |
592 GtkAllocation all; | 576 GtkAllocation all; |
593 | 577 |
594 all.y = mbheight + tbheight; | 578 all.y = mbheight + tbheight; |
677 unsigned long pixel; | 661 unsigned long pixel; |
678 GdkColor *c; | 662 GdkColor *c; |
679 { | 663 { |
680 GdkColormap *map = gtk_widget_get_colormap (w); | 664 GdkColormap *map = gtk_widget_get_colormap (w); |
681 gdk_colormap_query_color (map, pixel, c); | 665 gdk_colormap_query_color (map, pixel, c); |
682 } | |
683 | |
684 /* Turning off double buffering for our GtkFixed widget has the side | |
685 effect of turning it off also for its children (scroll bars). | |
686 But we want those to be double buffered to not flicker so handle | |
687 expose manually here. | |
688 WIDGET is the GtkFixed widget that gets exposed. | |
689 EVENT is the expose event. | |
690 USER_DATA is unused. | |
691 | |
692 Return TRUE to tell GTK that this expose event has been fully handeled | |
693 and that GTK shall do nothing more with it. */ | |
694 static gboolean | |
695 xg_fixed_handle_expose (GtkWidget *widget, | |
696 GdkEventExpose *event, | |
697 gpointer user_data) | |
698 { | |
699 GList *iter; | |
700 | |
701 for (iter = GTK_FIXED (widget)->children; iter; iter = g_list_next (iter)) | |
702 { | |
703 GtkFixedChild *child_data = (GtkFixedChild *) iter->data; | |
704 GtkWidget *child = child_data->widget; | |
705 GdkWindow *window = child->window; | |
706 GdkRegion *region = gtk_widget_region_intersect (child, event->region); | |
707 | |
708 if (! gdk_region_empty (region)) | |
709 { | |
710 GdkEvent child_event; | |
711 child_event.expose = *event; | |
712 child_event.expose.region = region; | |
713 | |
714 /* Turn on double buffering, i.e. draw to an off screen area. */ | |
715 gdk_window_begin_paint_region (window, region); | |
716 | |
717 /* Tell child to redraw itself. */ | |
718 gdk_region_get_clipbox (region, &child_event.expose.area); | |
719 gtk_widget_send_expose (child, &child_event); | |
720 gdk_window_process_updates (window, TRUE); | |
721 | |
722 /* Copy off screen area to the window. */ | |
723 gdk_window_end_paint (window); | |
724 } | |
725 | |
726 gdk_region_destroy (region); | |
727 } | |
728 | |
729 return TRUE; | |
730 } | 666 } |
731 | 667 |
732 /* Create and set up the GTK widgets for frame F. | 668 /* Create and set up the GTK widgets for frame F. |
733 Return 0 if creation failed, non-zero otherwise. */ | 669 Return 0 if creation failed, non-zero otherwise. */ |
734 int | 670 int |
801 with regular X drawing primitives, so from a GTK/GDK point of | 737 with regular X drawing primitives, so from a GTK/GDK point of |
802 view, the widget is totally blank. When an expose comes, this | 738 view, the widget is totally blank. When an expose comes, this |
803 will make the widget blank, and then Emacs redraws it. This flickers | 739 will make the widget blank, and then Emacs redraws it. This flickers |
804 a lot, so we turn off double buffering. */ | 740 a lot, so we turn off double buffering. */ |
805 gtk_widget_set_double_buffered (wfixed, FALSE); | 741 gtk_widget_set_double_buffered (wfixed, FALSE); |
806 | |
807 /* Turning off double buffering above has the side effect of turning | |
808 it off also for its children (scroll bars). But we want those | |
809 to be double buffered to not flicker so handle expose manually. */ | |
810 g_signal_connect (G_OBJECT (wfixed), "expose-event", | |
811 G_CALLBACK (xg_fixed_handle_expose), 0); | |
812 | 742 |
813 /* GTK documents says use gtk_window_set_resizable. But then a user | 743 /* GTK documents says use gtk_window_set_resizable. But then a user |
814 can't shrink the window from its starting size. */ | 744 can't shrink the window from its starting size. */ |
815 gtk_window_set_policy (GTK_WINDOW (wtop), TRUE, TRUE, TRUE); | 745 gtk_window_set_policy (GTK_WINDOW (wtop), TRUE, TRUE, TRUE); |
816 gtk_window_set_wmclass (GTK_WINDOW (wtop), | 746 gtk_window_set_wmclass (GTK_WINDOW (wtop), |
2768 struct scroll_bar *bar; | 2698 struct scroll_bar *bar; |
2769 GCallback scroll_callback; | 2699 GCallback scroll_callback; |
2770 char *scroll_bar_name; | 2700 char *scroll_bar_name; |
2771 { | 2701 { |
2772 GtkWidget *wscroll; | 2702 GtkWidget *wscroll; |
2703 GtkWidget *webox; | |
2773 GtkObject *vadj; | 2704 GtkObject *vadj; |
2774 int scroll_id; | 2705 int scroll_id; |
2775 | 2706 |
2776 /* Page, step increment values are not so important here, they | 2707 /* Page, step increment values are not so important here, they |
2777 will be corrected in x_set_toolkit_scroll_bar_thumb. */ | 2708 will be corrected in x_set_toolkit_scroll_bar_thumb. */ |
2778 vadj = gtk_adjustment_new (XG_SB_MIN, XG_SB_MIN, XG_SB_MAX, | 2709 vadj = gtk_adjustment_new (XG_SB_MIN, XG_SB_MIN, XG_SB_MAX, |
2779 0.1, 0.1, 0.1); | 2710 0.1, 0.1, 0.1); |
2780 | 2711 |
2781 wscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (vadj)); | 2712 wscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (vadj)); |
2713 webox = gtk_event_box_new (); | |
2782 gtk_widget_set_name (wscroll, scroll_bar_name); | 2714 gtk_widget_set_name (wscroll, scroll_bar_name); |
2783 gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS); | 2715 gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS); |
2784 | 2716 |
2785 scroll_id = xg_store_widget_in_map (wscroll); | 2717 scroll_id = xg_store_widget_in_map (wscroll); |
2786 | 2718 |
2802 g_signal_connect (G_OBJECT (wscroll), | 2734 g_signal_connect (G_OBJECT (wscroll), |
2803 "button-release-event", | 2735 "button-release-event", |
2804 G_CALLBACK (scroll_bar_button_cb), | 2736 G_CALLBACK (scroll_bar_button_cb), |
2805 (gpointer) bar); | 2737 (gpointer) bar); |
2806 | 2738 |
2807 gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), | 2739 /* The scroll bar widget does not draw on a window of its own. Instead |
2808 wscroll, -1, -1); | 2740 it draws on the parent window, in this case the edit widget. So |
2741 whenever the edit widget is cleared, the scroll bar needs to redraw | |
2742 also, which causes flicker. Put an event box between the edit widget | |
2743 and the scroll bar, so the scroll bar instead draws itself on the | |
2744 event box window. */ | |
2745 gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1); | |
2746 gtk_container_add (GTK_CONTAINER (webox), wscroll); | |
2747 | |
2809 | 2748 |
2810 /* Set the cursor to an arrow. */ | 2749 /* Set the cursor to an arrow. */ |
2811 xg_set_cursor (wscroll, FRAME_X_DISPLAY_INFO (f)->xg_cursor); | 2750 xg_set_cursor (webox, FRAME_X_DISPLAY_INFO (f)->xg_cursor); |
2812 | 2751 |
2813 SET_SCROLL_BAR_X_WINDOW (bar, scroll_id); | 2752 SET_SCROLL_BAR_X_WINDOW (bar, scroll_id); |
2814 } | 2753 } |
2815 | 2754 |
2816 /* Make the scroll bar represented by SCROLLBAR_ID visible. */ | 2755 /* Make the scroll bar represented by SCROLLBAR_ID visible. */ |
2818 xg_show_scroll_bar (scrollbar_id) | 2757 xg_show_scroll_bar (scrollbar_id) |
2819 int scrollbar_id; | 2758 int scrollbar_id; |
2820 { | 2759 { |
2821 GtkWidget *w = xg_get_widget_from_map (scrollbar_id); | 2760 GtkWidget *w = xg_get_widget_from_map (scrollbar_id); |
2822 if (w) | 2761 if (w) |
2823 gtk_widget_show (w); | 2762 gtk_widget_show_all (gtk_widget_get_parent (w)); |
2824 } | 2763 } |
2825 | 2764 |
2826 /* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */ | 2765 /* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */ |
2827 void | 2766 void |
2828 xg_remove_scroll_bar (f, scrollbar_id) | 2767 xg_remove_scroll_bar (f, scrollbar_id) |
2830 int scrollbar_id; | 2769 int scrollbar_id; |
2831 { | 2770 { |
2832 GtkWidget *w = xg_get_widget_from_map (scrollbar_id); | 2771 GtkWidget *w = xg_get_widget_from_map (scrollbar_id); |
2833 if (w) | 2772 if (w) |
2834 { | 2773 { |
2774 GtkWidget *wparent = gtk_widget_get_parent (w); | |
2835 gtk_widget_destroy (w); | 2775 gtk_widget_destroy (w); |
2776 gtk_widget_destroy (wparent); | |
2836 SET_FRAME_GARBAGED (f); | 2777 SET_FRAME_GARBAGED (f); |
2837 } | 2778 } |
2838 } | |
2839 | |
2840 /* Find left/top for widget W in GtkFixed widget WFIXED. */ | |
2841 static void | |
2842 xg_find_top_left_in_fixed (w, wfixed, left, top) | |
2843 GtkWidget *w, *wfixed; | |
2844 int *left, *top; | |
2845 { | |
2846 GList *iter; | |
2847 | |
2848 for (iter = GTK_FIXED (wfixed)->children; iter; iter = g_list_next (iter)) | |
2849 { | |
2850 GtkFixedChild *child = (GtkFixedChild *) iter->data; | |
2851 | |
2852 if (child->widget == w) | |
2853 { | |
2854 *left = child->x; | |
2855 *top = child->y; | |
2856 return; | |
2857 } | |
2858 } | |
2859 | |
2860 /* Shall never end up here. */ | |
2861 abort (); | |
2862 } | 2779 } |
2863 | 2780 |
2864 /* Update the position of the vertical scroll bar represented by SCROLLBAR_ID | 2781 /* Update the position of the vertical scroll bar represented by SCROLLBAR_ID |
2865 in frame F. | 2782 in frame F. |
2866 TOP/LEFT are the new pixel positions where the bar shall appear. | 2783 TOP/LEFT are the new pixel positions where the bar shall appear. |
2867 WIDTH, HEIGHT is the size in pixels the bar shall have. */ | 2784 WIDTH, HEIGHT is the size in pixels the bar shall have. */ |
2868 void | 2785 void |
2869 xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height, | 2786 xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height) |
2870 real_left, canon_width) | |
2871 FRAME_PTR f; | 2787 FRAME_PTR f; |
2872 int scrollbar_id; | 2788 int scrollbar_id; |
2873 int top; | 2789 int top; |
2874 int left; | 2790 int left; |
2875 int width; | 2791 int width; |
2879 GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); | 2795 GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id); |
2880 | 2796 |
2881 if (wscroll) | 2797 if (wscroll) |
2882 { | 2798 { |
2883 GtkWidget *wfixed = f->output_data.x->edit_widget; | 2799 GtkWidget *wfixed = f->output_data.x->edit_widget; |
2884 | 2800 GtkWidget *wparent = gtk_widget_get_parent (wscroll); |
2885 gtk_container_set_reallocate_redraws (GTK_CONTAINER (wfixed), TRUE); | |
2886 | 2801 |
2887 /* Move and resize to new values. */ | 2802 /* Move and resize to new values. */ |
2888 gtk_fixed_move (GTK_FIXED (wfixed), wscroll, left, top); | |
2889 gtk_widget_set_size_request (wscroll, width, height); | 2803 gtk_widget_set_size_request (wscroll, width, height); |
2890 | 2804 gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top); |
2891 /* Scroll bars in GTK has a fixed width, so if we say width 16, it | 2805 |
2892 will only be its fixed width (14 is default) anyway, the rest is | |
2893 blank. We are drawing the mode line across scroll bars when | |
2894 the frame is split: | |
2895 |bar| |fringe| | |
2896 ---------------- | |
2897 mode line | |
2898 ---------------- | |
2899 |bar| |fringe| | |
2900 | |
2901 When we "unsplit" the frame: | |
2902 | |
2903 |bar| |fringe| | |
2904 -| |-| | | |
2905 m¦ |i| | | |
2906 -| |-| | | |
2907 | | | | | |
2908 | |
2909 | |
2910 the remains of the mode line can be seen in these blank spaces. | |
2911 So we must clear them explicitly. | |
2912 GTK scroll bars should do that, but they don't. | |
2913 Also, the canonical width may be wider than the width for the | |
2914 scroll bar so that there is some space (typically 1 pixel) between | |
2915 the scroll bar and the edge of the window and between the scroll | |
2916 bar and the fringe. */ | |
2917 gdk_window_clear (wscroll->window); | |
2918 | |
2919 /* Must force out update so changed scroll bars gets redrawn. */ | |
2920 gdk_window_process_all_updates (); | |
2921 | |
2922 SET_FRAME_GARBAGED (f); | 2806 SET_FRAME_GARBAGED (f); |
2923 cancel_mouse_face (f); | 2807 cancel_mouse_face (f); |
2924 } | 2808 } |
2925 } | 2809 } |
2926 | 2810 |