Mercurial > hg > xemacs-beta
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; |