comparison src/frame.c @ 5105:d76a51b29d91

fix Stephen's bug with frame sizing -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-03-05 Ben Wing <ben@xemacs.org> * frame.c: * frame.c (Fframe_pixel_height): * frame.c (Fframe_displayable_pixel_height): * frame.c (Fframe_pixel_width): * frame.c (Fframe_displayable_pixel_width): * frame.c (Fset_frame_pixel_height): * frame.c (Fset_frame_displayable_pixel_height): * frame.c (Fset_frame_pixel_width): * frame.c (Fset_frame_displayable_pixel_width): * frame.c (get_frame_char_size): * frame.c (change_frame_size_1): Make it so that `frame-pixel-height', `set-frame-pixel-height', etc. use updated values for the displayable or total pixel size that will reflect what will happen as of the next redisplay. This basically means using the character-cell height and converting on-the-fly to pixel units. In the process, make sure FRAME_CHARWIDTH/ FRAME_CHARHEIGHT are always correct and change get_frame_char_size() to simply use them; the old logic in that function was inlined into change_frame_size_1(), which is the only place that needs the logic.
author Ben Wing <ben@xemacs.org>
date Sat, 06 Mar 2010 00:01:04 -0600
parents 868a5349acee
children c113da3e2f67
comparison
equal deleted inserted replaced
5104:868a5349acee 5105:d76a51b29d91
484 int source_width, int source_height, 484 int source_width, int source_height,
485 enum frame_size_type dest, 485 enum frame_size_type dest,
486 int *dest_width, int *dest_height); 486 int *dest_width, int *dest_height);
487 static void get_frame_char_size (struct frame *f, int *out_width, 487 static void get_frame_char_size (struct frame *f, int *out_width,
488 int *out_height); 488 int *out_height);
489 static void get_frame_displayable_pixel_size (struct frame *f, int *out_width, 489 static void get_frame_new_displayable_pixel_size (struct frame *f,
490 int *out_height); 490 int *out_width,
491 int *out_height);
492 static void get_frame_new_total_pixel_size (struct frame *f,
493 int *out_width,
494 int *out_height);
491 495
492 static struct display_line title_string_display_line; 496 static struct display_line title_string_display_line;
493 /* Used by generate_title_string. Global because they get used so much that 497 /* Used by generate_title_string. Global because they get used so much that
494 the dynamic allocation time adds up. */ 498 the dynamic allocation time adds up. */
495 static Ichar_dynarr *title_string_ichar_dynarr; 499 static Ichar_dynarr *title_string_ichar_dynarr;
3076 DEFUN ("frame-pixel-height", Fframe_pixel_height, 0, 1, 0, /* 3080 DEFUN ("frame-pixel-height", Fframe_pixel_height, 0, 1, 0, /*
3077 Return the total height in pixels of FRAME. 3081 Return the total height in pixels of FRAME.
3078 */ 3082 */
3079 (frame)) 3083 (frame))
3080 { 3084 {
3081 return make_int (decode_frame (frame)->pixheight); 3085 struct frame *f = decode_frame (frame);
3086 int width, height;
3087
3088 get_frame_new_total_pixel_size (f, &width, &height);
3089 return make_int (height);
3082 } 3090 }
3083 3091
3084 DEFUN ("frame-displayable-pixel-height", Fframe_displayable_pixel_height, 0, 1, 0, /* 3092 DEFUN ("frame-displayable-pixel-height", Fframe_displayable_pixel_height, 0, 1, 0, /*
3085 Return the height of the displayable area in pixels of FRAME. 3093 Return the height of the displayable area in pixels of FRAME.
3086 */ 3094 */
3087 (frame)) 3095 (frame))
3088 { 3096 {
3089 struct frame *f = decode_frame (frame); 3097 struct frame *f = decode_frame (frame);
3090 int width, height; 3098 int width, height;
3091 3099
3092 get_frame_displayable_pixel_size (f, &width, &height); 3100 get_frame_new_displayable_pixel_size (f, &width, &height);
3093 return make_int (height); 3101 return make_int (height);
3094 } 3102 }
3095 3103
3096 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /* 3104 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /*
3097 Return the total width in pixels of FRAME. 3105 Return the total width in pixels of FRAME.
3098 */ 3106 */
3099 (frame)) 3107 (frame))
3100 { 3108 {
3101 return make_int (decode_frame (frame)->pixwidth); 3109 struct frame *f = decode_frame (frame);
3110 int width, height;
3111
3112 get_frame_new_total_pixel_size (f, &width, &height);
3113 return make_int (width);
3102 } 3114 }
3103 3115
3104 DEFUN ("frame-displayable-pixel-width", Fframe_displayable_pixel_width, 0, 1, 0, /* 3116 DEFUN ("frame-displayable-pixel-width", Fframe_displayable_pixel_width, 0, 1, 0, /*
3105 Return the width of the displayable area in pixels of FRAME. 3117 Return the width of the displayable area in pixels of FRAME.
3106 */ 3118 */
3107 (frame)) 3119 (frame))
3108 { 3120 {
3109 struct frame *f = decode_frame (frame); 3121 struct frame *f = decode_frame (frame);
3110 int width, height; 3122 int width, height;
3111 3123
3112 get_frame_displayable_pixel_size (f, &width, &height); 3124 get_frame_new_displayable_pixel_size (f, &width, &height);
3113 return make_int (width); 3125 return make_int (width);
3114 } 3126 }
3115 3127
3116 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /* 3128 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /*
3117 Specify that the frame FRAME has LINES lines. 3129 Specify that the frame FRAME has LINES lines.
3145 struct frame *f = decode_frame (frame); 3157 struct frame *f = decode_frame (frame);
3146 int pwidth, pheight; 3158 int pwidth, pheight;
3147 int guwidth, guheight; 3159 int guwidth, guheight;
3148 3160
3149 CHECK_INT (height); 3161 CHECK_INT (height);
3162 get_frame_new_total_pixel_size (f, &pwidth, &pheight);
3150 pheight = XINT (height); 3163 pheight = XINT (height);
3151 pwidth = FRAME_PIXWIDTH (f);
3152 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight, 3164 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
3153 SIZE_FRAME_UNIT, &guwidth, &guheight); 3165 SIZE_FRAME_UNIT, &guwidth, &guheight);
3154 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend)); 3166 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3155 return wrap_frame (f); 3167 return wrap_frame (f);
3156 } 3168 }
3166 struct frame *f = decode_frame (frame); 3178 struct frame *f = decode_frame (frame);
3167 int pwidth, pheight; 3179 int pwidth, pheight;
3168 int guwidth, guheight; 3180 int guwidth, guheight;
3169 3181
3170 CHECK_INT (height); 3182 CHECK_INT (height);
3171 get_frame_displayable_pixel_size (f, &pwidth, &pheight); 3183 get_frame_new_displayable_pixel_size (f, &pwidth, &pheight);
3172 pheight = XINT (height); 3184 pheight = XINT (height);
3173 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight, 3185 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
3174 SIZE_FRAME_UNIT, &guwidth, &guheight); 3186 SIZE_FRAME_UNIT, &guwidth, &guheight);
3175 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend)); 3187 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3176 return wrap_frame (f); 3188 return wrap_frame (f);
3209 struct frame *f = decode_frame (frame); 3221 struct frame *f = decode_frame (frame);
3210 int pwidth, pheight; 3222 int pwidth, pheight;
3211 int guwidth, guheight; 3223 int guwidth, guheight;
3212 3224
3213 CHECK_INT (width); 3225 CHECK_INT (width);
3226 get_frame_new_total_pixel_size (f, &pwidth, &pheight);
3214 pwidth = XINT (width); 3227 pwidth = XINT (width);
3215 pheight = FRAME_PIXHEIGHT (f);
3216 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight, 3228 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
3217 SIZE_FRAME_UNIT, &guwidth, &guheight); 3229 SIZE_FRAME_UNIT, &guwidth, &guheight);
3218 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend)); 3230 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3219 return wrap_frame (f); 3231 return wrap_frame (f);
3220 } 3232 }
3230 struct frame *f = decode_frame (frame); 3242 struct frame *f = decode_frame (frame);
3231 int pwidth, pheight; 3243 int pwidth, pheight;
3232 int guwidth, guheight; 3244 int guwidth, guheight;
3233 3245
3234 CHECK_INT (width); 3246 CHECK_INT (width);
3235 get_frame_displayable_pixel_size (f, &pwidth, &pheight); 3247 get_frame_new_displayable_pixel_size (f, &pwidth, &pheight);
3236 pwidth = XINT (width); 3248 pwidth = XINT (width);
3237 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight, 3249 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
3238 SIZE_FRAME_UNIT, &guwidth, &guheight); 3250 SIZE_FRAME_UNIT, &guwidth, &guheight);
3239 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend)); 3251 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3240 return wrap_frame (f); 3252 return wrap_frame (f);
3562 int char_height; 3574 int char_height;
3563 pixel_to_char_size (f, in_width, in_height, &char_width, &char_height); 3575 pixel_to_char_size (f, in_width, in_height, &char_width, &char_height);
3564 char_to_pixel_size (f, char_width, char_height, out_width, out_height); 3576 char_to_pixel_size (f, char_width, char_height, out_width, out_height);
3565 } 3577 }
3566 3578
3567 /* Get the frame size in character cells, recalculating on the fly.
3568 #### The logic of this function follows former logic elsewhere,
3569 which used FRAME_PIXWIDTH() on pixelated-geometry systems but
3570 FRAME_WIDTH() on non-pixelated-geometry systems. Not clear why not
3571 always just use one or the other.
3572
3573 Why don't we just use FRAME_CHARWIDTH() etc. in get_frame_char_size()?
3574 That wouldn't work because change_frame_size_1() depends on the
3575 following function to *set* the values of FRAME_CHARWIDTH() etc.
3576
3577 But elsewhere I suppose we could use it.
3578 */
3579
3580 static void 3579 static void
3581 get_frame_char_size (struct frame *f, int *out_width, int *out_height) 3580 get_frame_char_size (struct frame *f, int *out_width, int *out_height)
3582 { 3581 {
3583 if (window_system_pixelated_geometry (wrap_frame (f))) 3582 *out_width = FRAME_CHARWIDTH (f);
3584 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f), 3583 *out_height = FRAME_CHARHEIGHT (f);
3585 out_width, out_height); 3584 }
3586 else 3585
3587 { 3586 /* Return the "new" frame size in displayable pixels, which will be
3588 *out_width = FRAME_WIDTH (f); 3587 accurate as of next redisplay. If we have changed the default font or
3589 *out_height = FRAME_HEIGHT (f); 3588 toolbar or scrollbar specifiers, the frame pixel size will change as of
3590 } 3589 next redisplay, but the frame character-cell size will remain the same.
3591 } 3590 So use those dimensions to compute the displayable-pixel size. */
3592 3591
3593 static void 3592 static void
3594 get_frame_displayable_pixel_size (struct frame *f, int *out_width, 3593 get_frame_new_displayable_pixel_size (struct frame *f, int *out_width,
3595 int *out_height) 3594 int *out_height)
3596 { 3595 {
3597 frame_conversion_internal (f, SIZE_FRAME_UNIT, FRAME_WIDTH (f), 3596 frame_conversion_internal (f, SIZE_CHAR_CELL, FRAME_CHARWIDTH (f),
3598 FRAME_HEIGHT (f), SIZE_DISPLAYABLE_PIXEL, 3597 FRAME_CHARHEIGHT (f), SIZE_DISPLAYABLE_PIXEL,
3598 out_width, out_height);
3599 }
3600
3601 /* Return the "new" frame size in total pixels, which will be
3602 accurate as of next redisplay. See get_frame_new_displayable_pixel_size().
3603 */
3604
3605
3606 static void
3607 get_frame_new_total_pixel_size (struct frame *f, int *out_width,
3608 int *out_height)
3609 {
3610 frame_conversion_internal (f, SIZE_CHAR_CELL, FRAME_CHARWIDTH (f),
3611 FRAME_CHARHEIGHT (f), SIZE_TOTAL_PIXEL,
3599 out_width, out_height); 3612 out_width, out_height);
3600 } 3613 }
3601 3614
3602 3615
3603 /**************************************************************************/ 3616 /**************************************************************************/
3611 on MS Windows or generally on pixelated-geometry window systems). */ 3624 on MS Windows or generally on pixelated-geometry window systems). */
3612 static void 3625 static void
3613 change_frame_size_1 (struct frame *f, int newwidth, int newheight) 3626 change_frame_size_1 (struct frame *f, int newwidth, int newheight)
3614 { 3627 {
3615 int new_pixheight, new_pixwidth; 3628 int new_pixheight, new_pixwidth;
3629 int paned_pixheight, paned_pixwidth;
3616 int real_font_height, real_font_width; 3630 int real_font_height, real_font_width;
3617 3631
3618 /* #### Chuck -- shouldn't we be checking to see if the frame 3632 /* #### Chuck -- shouldn't we be checking to see if the frame
3619 is being "changed" to its existing size, and do nothing if so? */ 3633 is being "changed" to its existing size, and do nothing if so? */
3620 /* No, because it would hose toolbar updates. The toolbar 3634 /* No, because it would hose toolbar updates. The toolbar
3639 FRAME_NEW_WIDTH (f) = 0; 3653 FRAME_NEW_WIDTH (f) = 0;
3640 3654
3641 /* We need to remove the boundaries of the paned area (see top of file) 3655 /* We need to remove the boundaries of the paned area (see top of file)
3642 from the total-area pixel size, which is what we have now. 3656 from the total-area pixel size, which is what we have now.
3643 */ 3657 */
3644 new_pixheight -= 3658 paned_pixheight = new_pixheight -
3645 (FRAME_NONPANED_SIZE (f, TOP_EDGE) + FRAME_NONPANED_SIZE (f, BOTTOM_EDGE)); 3659 (FRAME_NONPANED_SIZE (f, TOP_EDGE) + FRAME_NONPANED_SIZE (f, BOTTOM_EDGE));
3646 new_pixwidth -= 3660 paned_pixwidth = new_pixwidth -
3647 (FRAME_NONPANED_SIZE (f, LEFT_EDGE) + FRAME_NONPANED_SIZE (f, RIGHT_EDGE)); 3661 (FRAME_NONPANED_SIZE (f, LEFT_EDGE) + FRAME_NONPANED_SIZE (f, RIGHT_EDGE));
3648 3662
3649 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = FRAME_PANED_TOP_EDGE (f); 3663 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = FRAME_PANED_TOP_EDGE (f);
3650 3664
3651 if (FRAME_HAS_MINIBUF_P (f) 3665 if (FRAME_HAS_MINIBUF_P (f)
3660 * default font height. This should cause the minibuffer 3674 * default font height. This should cause the minibuffer
3661 * height to be recomputed on font changes but not for 3675 * height to be recomputed on font changes but not for
3662 * other frame size changes, which seems reasonable. 3676 * other frame size changes, which seems reasonable.
3663 */ 3677 */
3664 int old_minibuf_height = 3678 int old_minibuf_height =
3665 XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height; 3679 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_height;
3666 int minibuf_height = 3680 int minibuf_height =
3667 f->init_finished && (old_minibuf_height % real_font_height) == 0 ? 3681 f->init_finished && (old_minibuf_height % real_font_height) == 0 ?
3668 max(old_minibuf_height, real_font_height) : 3682 max (old_minibuf_height, real_font_height) :
3669 real_font_height; 3683 real_font_height;
3670 set_window_pixheight (FRAME_ROOT_WINDOW (f), 3684 set_window_pixheight (FRAME_ROOT_WINDOW (f),
3671 /* - font_height for minibuffer */ 3685 /* - font_height for minibuffer */
3672 new_pixheight - minibuf_height, 0); 3686 paned_pixheight - minibuf_height, 0);
3673 3687
3674 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top = 3688 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top =
3675 FRAME_PANED_TOP_EDGE (f) + 3689 FRAME_PANED_TOP_EDGE (f) +
3676 FRAME_BOTTOM_GUTTER_BOUNDS (f) + 3690 FRAME_BOTTOM_GUTTER_BOUNDS (f) +
3677 new_pixheight - minibuf_height; 3691 paned_pixheight - minibuf_height;
3678 3692
3679 set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0); 3693 set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0);
3680 } 3694 }
3681 else 3695 else
3682 /* Frame has just one top-level window. */ 3696 /* Frame has just one top-level window. */
3683 set_window_pixheight (FRAME_ROOT_WINDOW (f), new_pixheight, 0); 3697 set_window_pixheight (FRAME_ROOT_WINDOW (f), paned_pixheight, 0);
3684 3698
3685 FRAME_HEIGHT (f) = newheight; 3699 FRAME_HEIGHT (f) = newheight;
3686 if (FRAME_TTY_P (f)) 3700 if (FRAME_TTY_P (f))
3687 f->pixheight = newheight; 3701 f->pixheight = newheight;
3688 3702
3689 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = FRAME_PANED_LEFT_EDGE (f); 3703 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = FRAME_PANED_LEFT_EDGE (f);
3690 set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0); 3704 set_window_pixwidth (FRAME_ROOT_WINDOW (f), paned_pixwidth, 0);
3691 3705
3692 if (FRAME_HAS_MINIBUF_P (f)) 3706 if (FRAME_HAS_MINIBUF_P (f))
3693 { 3707 {
3694 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left = 3708 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left =
3695 FRAME_PANED_LEFT_EDGE (f); 3709 FRAME_PANED_LEFT_EDGE (f);
3696 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0); 3710 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), paned_pixwidth, 0);
3697 } 3711 }
3698 3712
3699 FRAME_WIDTH (f) = newwidth; 3713 FRAME_WIDTH (f) = newwidth;
3700 if (FRAME_TTY_P (f)) 3714 if (FRAME_TTY_P (f))
3701 f->pixwidth = newwidth; 3715 f->pixwidth = newwidth;
3702 3716
3703 /* #### On MS Windows, this references FRAME_PIXWIDTH() and 3717 /* Set the frame character-cell width appropriately. */
3704 FRAME_PIXHEIGHT(). I'm not sure we can count on those values being 3718 if (window_system_pixelated_geometry (wrap_frame (f)))
3705 set. Instead we should use the total pixel size we got near the top 3719 pixel_to_char_size (f, new_pixwidth, new_pixheight,
3706 by calling frame_conversion_internal(). We should inline the logic in 3720 &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
3707 get_frame_char_size() here and change that function so it just looks 3721 else
3708 at FRAME_CHARWIDTH() and FRAME_CHARHEIGHT(). */ 3722 {
3709 get_frame_char_size (f, &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f)); 3723 FRAME_CHARWIDTH (f) = FRAME_WIDTH (f);
3724 FRAME_CHARHEIGHT (f) = FRAME_HEIGHT (f);
3725 }
3710 3726
3711 MARK_FRAME_TOOLBARS_CHANGED (f); 3727 MARK_FRAME_TOOLBARS_CHANGED (f);
3712 MARK_FRAME_GUTTERS_CHANGED (f); 3728 MARK_FRAME_GUTTERS_CHANGED (f);
3713 MARK_FRAME_CHANGED (f); 3729 MARK_FRAME_CHANGED (f);
3714 f->echo_area_garbaged = 1; 3730 f->echo_area_garbaged = 1;