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