diff options
| author | Martin Rudalics | 2015-10-13 12:11:43 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2015-10-13 12:11:43 +0200 |
| commit | d4fe840df0b5fdb3aed538fae2ced143a471f60a (patch) | |
| tree | 13ff9d7115616a99af7e0257277a1ca6edf31f72 /src/widget.c | |
| parent | e53e1a0426539aa3f2902632fdd8025da8f710f2 (diff) | |
| download | emacs-d4fe840df0b5fdb3aed538fae2ced143a471f60a.tar.gz emacs-d4fe840df0b5fdb3aed538fae2ced143a471f60a.zip | |
Allow setting frame pixel sizes from frame parameters (Bug#21415)
Also fix some misfeatures in frame (re-)sizing code, add more
debugging information and remove some dead code.
* lisp/frame.el (frame-notice-user-settings, make-frame): Change
parameter names when setting `frame-size-history'.
(frame--size-history): New function.
* src/frame.c (frame_inhibit_resize): If frame has not been made
yet, return t if inhibit_horizontal_resize or
inhibit_vertical_resize bit have been set.
(adjust_frame_size): Simplify.
(make_frame): Initialize inhibit_horizontal_resize,
inhibit_vertical_resize, tool_bar_redisplayed, tool_bar_resized.
(Fframe_after_make_frame): Reset inhibit_horizontal_resize and
inhibit_vertical_resize slots.
(x_set_frame_parameters): Handle `text-pixels' specification for
width and height parameters. Don't consider new_height or
new_width changes. Call adjust_frame_size instead of
Fset_frame_size.
(x_figure_window_size): Two new arguments x_width and y_width
returning frame's figures width and height. Calculate tool bar
height before frame sizes so SET_FRAME_HEIGHT can pick it up.
Handle `text-pixels' specification for width and height
parameters.
(Qtext_pixels, Qx_set_frame_parameters, Qset_frame_size)
(Qx_set_window_size_1, Qx_set_window_size_2)
(Qx_set_window_size_3, Qx_set_menu_bar_lines)
(Qupdate_frame_menubar, Qfree_frame_menubar_1)
(Qfree_frame_menubar_2): New symbols.
* src/frame.h (structure frame): New booleans
tool_bar_redisplayed, tool_bar_resized,
inhibit_horizontal_resize, inhibit_vertical_resize.
(x_figure_window_size): Update external declaration.
* src/gtkutil.c (xg_frame_set_char_size): Set size hints before
calling gtk_window_resize.
(update_frame_tool_bar): Make inhibiting of frame resizing more
discriminative. Set tool_bar_resized bit.
* src/nsfns.m (x_set_tool_bar_lines): Make inhibiting of frame
resizing more discriminative. Call adjust_frame_size instead of
x_set_window_size.
(Fx_create_frame): Handle x_width and x_height if
set by x_figure_window_size.
* src/nsterm.m (x_set_window_size): For GNUSTEP build don't
subtract 3 from tool bar height.
(x_set_window_size): Add frame_size_history_add call.
(x_new_font): Call adjust_frame_size instead of
x_set_window_size.
* src/w32fns.c (x_change_tool_bar_height): Reset
tool_bar_redisplayed and tool_bar_resized bits when adding tool
bar. Make inhibiting of frame resizing more discriminative.
(w32_wnd_proc): Remove dead code in WM_WINDOWPOSCHANGING case.
(Fx_create_frame): Handle x_width and x_height if set by
x_figure_window_size. Set size hints before adjusting frame size.
(x_create_tip_frame): Adjust x_figure_window_size call.
* src/w32term.c (x_set_window_size): Add frame_size_history_add
call.
* src/widget.c (set_frame_size): Remove dead code. Add
frame_size_history_add call. When frame_resize_pixelwise is t
use FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT instead of
pixel_width and pixel_height.
(update_various_frame_slots): Remove dead code.
(EmacsFrameResize): Add more information in
frame_size_history_add call.
(EmacsFrameQueryGeometry): Round only when frame_resize_pixelwise
is not set.
* src/xdisp.c (redisplay_tool_bar): Set tool_bar_redisplayed bits.
* src/xfns.c (x_set_menu_bar_lines): Change argument name.
(x_change_tool_bar_height): Reset tool_bar_redisplayed and
tool_bar_resized bits when adding tool bar. Make inhibiting of
frame resizing more discriminative.
(Fx_create_frame): Handle x_width and x_height if set by
x_figure_window_size. Set size hints before adjusting frame size.
(x_create_tip_frame): Adjust x_figure_window_size call.
* src/xmenu.c (update_frame_menubar): Don't handle Lucid specially.
(set_frame_menubar): On Lucid never add core-border-width to
avoid that adding XtNinternalBorderWidth adds it again.
(free_frame_menubar): Handle frame_inhibit_resize true for Motif.
* src/xterm.c (x_new_font): In non-toolkit case handle size
change of menu bar.
(x_set_window_size_1): Fix calls to frame_size_history_add.
(x_wm_set_size_hint): Remove dead code. Set
size_hints.min_width and size_hints.min_height to base_width and
base_height.
Diffstat (limited to 'src/widget.c')
| -rw-r--r-- | src/widget.c | 196 |
1 files changed, 25 insertions, 171 deletions
diff --git a/src/widget.c b/src/widget.c index 0986ba61dbf..48872f55938 100644 --- a/src/widget.c +++ b/src/widget.c | |||
| @@ -268,167 +268,26 @@ set_frame_size (EmacsFrame ew) | |||
| 268 | */ | 268 | */ |
| 269 | 269 | ||
| 270 | /* Hairily merged geometry */ | 270 | /* Hairily merged geometry */ |
| 271 | int w = FRAME_COLS (ew->emacs_frame.frame); | 271 | struct frame *f = ew->emacs_frame.frame; |
| 272 | int h = FRAME_LINES (ew->emacs_frame.frame); | 272 | int w = FRAME_COLS (f); |
| 273 | 273 | int h = FRAME_LINES (f); | |
| 274 | Widget wmshell = get_wm_shell ((Widget) ew); | 274 | Widget wmshell = get_wm_shell ((Widget) ew); |
| 275 | Dimension pixel_width, pixel_height; | ||
| 275 | /* Each Emacs shell is now independent and top-level. */ | 276 | /* Each Emacs shell is now independent and top-level. */ |
| 276 | 277 | ||
| 277 | if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort (); | 278 | if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort (); |
| 278 | 279 | ||
| 279 | /* We don't need this for the moment. The geometry is computed in | 280 | char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height); |
| 280 | xfns.c. */ | 281 | ew->core.width = (frame_resize_pixelwise |
| 281 | #if 0 | 282 | ? FRAME_PIXEL_WIDTH (f) |
| 282 | /* If the EmacsFrame doesn't have a geometry but the shell does, | 283 | : pixel_width); |
| 283 | treat that as the geometry of the frame. (Is this bogus? | 284 | ew->core.height = (frame_resize_pixelwise |
| 284 | I'm not sure.) */ | 285 | ? FRAME_PIXEL_HEIGHT (f) |
| 285 | if (ew->emacs_frame.geometry == 0) | 286 | : pixel_height); |
| 286 | XtVaGetValues (wmshell, XtNgeometry, &ew->emacs_frame.geometry, NULL); | ||
| 287 | |||
| 288 | /* If the Shell is iconic, then the EmacsFrame is iconic. (Is | ||
| 289 | this bogus? I'm not sure.) */ | ||
| 290 | if (!ew->emacs_frame.iconic) | ||
| 291 | XtVaGetValues (wmshell, XtNiconic, &ew->emacs_frame.iconic, NULL); | ||
| 292 | |||
| 293 | |||
| 294 | { | ||
| 295 | char *geom = 0; | ||
| 296 | XtVaGetValues (app_shell, XtNgeometry, &geom, NULL); | ||
| 297 | if (geom) | ||
| 298 | app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h); | ||
| 299 | } | ||
| 300 | |||
| 301 | if (ew->emacs_frame.geometry) | ||
| 302 | frame_flags = XParseGeometry (ew->emacs_frame.geometry, | ||
| 303 | &frame_x, &frame_y, | ||
| 304 | &frame_w, &frame_h); | ||
| 305 | |||
| 306 | if (first_frame_p) | ||
| 307 | { | ||
| 308 | /* If this is the first frame created: | ||
| 309 | ==================================== | ||
| 310 | |||
| 311 | - Use the ApplicationShell's size/position, if specified. | ||
| 312 | (This is "Emacs.geometry", or the "-geometry" command line arg.) | ||
| 313 | - Else use the EmacsFrame's size/position. | ||
| 314 | (This is "*Frame-NAME.geometry") | ||
| 315 | |||
| 316 | - If the AppShell is iconic, the frame should be iconic. | ||
| 317 | |||
| 318 | AppShell comes first so that -geometry always applies to the first | ||
| 319 | frame created, even if there is an "every frame" entry in the | ||
| 320 | resource database. | ||
| 321 | */ | ||
| 322 | if (app_flags & (XValue | YValue)) | ||
| 323 | { | ||
| 324 | x = app_x; y = app_y; | ||
| 325 | flags |= (app_flags & (XValue | YValue | XNegative | YNegative)); | ||
| 326 | } | ||
| 327 | else if (frame_flags & (XValue | YValue)) | ||
| 328 | { | ||
| 329 | x = frame_x; y = frame_y; | ||
| 330 | flags |= (frame_flags & (XValue | YValue | XNegative | YNegative)); | ||
| 331 | } | ||
| 332 | |||
| 333 | if (app_flags & (WidthValue | HeightValue)) | ||
| 334 | { | ||
| 335 | w = app_w; h = app_h; | ||
| 336 | flags |= (app_flags & (WidthValue | HeightValue)); | ||
| 337 | } | ||
| 338 | else if (frame_flags & (WidthValue | HeightValue)) | ||
| 339 | { | ||
| 340 | w = frame_w; h = frame_h; | ||
| 341 | flags |= (frame_flags & (WidthValue | HeightValue)); | ||
| 342 | } | ||
| 343 | |||
| 344 | /* If the AppShell is iconic, then the EmacsFrame is iconic. */ | ||
| 345 | if (!ew->emacs_frame.iconic) | ||
| 346 | XtVaGetValues (app_shell, XtNiconic, &ew->emacs_frame.iconic, NULL); | ||
| 347 | |||
| 348 | first_frame_p = False; | ||
| 349 | } | ||
| 350 | else | ||
| 351 | { | ||
| 352 | /* If this is not the first frame created: | ||
| 353 | ======================================== | ||
| 354 | |||
| 355 | - use the EmacsFrame's size/position if specified | ||
| 356 | - Otherwise, use the ApplicationShell's size, but not position. | ||
| 357 | |||
| 358 | So that means that one can specify the position of the first frame | ||
| 359 | with "Emacs.geometry" or `-geometry'; but can only specify the | ||
| 360 | position of subsequent frames with "*Frame-NAME.geometry". | ||
| 361 | |||
| 362 | AppShell comes second so that -geometry does not apply to subsequent | ||
| 363 | frames when there is an "every frame" entry in the resource db, | ||
| 364 | but does apply to the first frame. | ||
| 365 | */ | ||
| 366 | if (frame_flags & (XValue | YValue)) | ||
| 367 | { | ||
| 368 | x = frame_x; y = frame_y; | ||
| 369 | flags |= (frame_flags & (XValue | YValue | XNegative | YNegative)); | ||
| 370 | } | ||
| 371 | 287 | ||
| 372 | if (frame_flags & (WidthValue | HeightValue)) | 288 | frame_size_history_add |
| 373 | { | 289 | (f, Qset_frame_size, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), |
| 374 | w = frame_w; h = frame_h; | 290 | list2 (make_number (ew->core.width), make_number (ew->core.height))); |
| 375 | flags |= (frame_flags & (WidthValue | HeightValue)); | ||
| 376 | } | ||
| 377 | else if (app_flags & (WidthValue | HeightValue)) | ||
| 378 | { | ||
| 379 | w = app_w; | ||
| 380 | h = app_h; | ||
| 381 | flags |= (app_flags & (WidthValue | HeightValue)); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | #endif /* 0 */ | ||
| 385 | { | ||
| 386 | Dimension pixel_width, pixel_height; | ||
| 387 | |||
| 388 | /* Take into account the size of the scrollbar. Always use the | ||
| 389 | number of columns occupied by the scroll bar here otherwise we | ||
| 390 | might end up with a frame width that is not a multiple of the | ||
| 391 | frame's character width which is bad for vertically split | ||
| 392 | windows. */ | ||
| 393 | |||
| 394 | #if 0 /* This can run Lisp code, and it is dangerous to give | ||
| 395 | out the frame to Lisp code before it officially exists. | ||
| 396 | This is handled in Fx_create_frame so not needed here. */ | ||
| 397 | change_frame_size (f, w, h, 1, 0, 0, 0); | ||
| 398 | #endif | ||
| 399 | char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height); | ||
| 400 | ew->core.width = pixel_width; | ||
| 401 | ew->core.height = pixel_height; | ||
| 402 | |||
| 403 | #if 0 /* xfns.c takes care of this now. */ | ||
| 404 | /* If a position was specified, assign it to the shell widget. | ||
| 405 | (Else WM won't do anything with it.) | ||
| 406 | */ | ||
| 407 | if (flags & (XValue | YValue)) | ||
| 408 | { | ||
| 409 | /* the tricky things with the sign is to make sure that | ||
| 410 | -0 is printed -0. */ | ||
| 411 | sprintf (shell_position, "=%c%d%c%d", | ||
| 412 | flags & XNegative ? '-' : '+', x < 0 ? -x : x, | ||
| 413 | flags & YNegative ? '-' : '+', y < 0 ? -y : y); | ||
| 414 | XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL); | ||
| 415 | } | ||
| 416 | else if (flags & (WidthValue | HeightValue)) | ||
| 417 | { | ||
| 418 | sprintf (shell_position, "=%dx%d", pixel_width, pixel_height); | ||
| 419 | XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL); | ||
| 420 | } | ||
| 421 | |||
| 422 | /* If the geometry spec we're using has W/H components, mark the size | ||
| 423 | in the WM_SIZE_HINTS as user specified. */ | ||
| 424 | if (flags & (WidthValue | HeightValue)) | ||
| 425 | mark_shell_size_user_specified (wmshell); | ||
| 426 | |||
| 427 | /* Also assign the iconic status of the frame to the Shell, so that | ||
| 428 | the WM sees it. */ | ||
| 429 | XtVaSetValues (wmshell, XtNiconic, ew->emacs_frame.iconic, NULL); | ||
| 430 | #endif /* 0 */ | ||
| 431 | } | ||
| 432 | } | 291 | } |
| 433 | 292 | ||
| 434 | static void | 293 | static void |
| @@ -486,16 +345,6 @@ update_various_frame_slots (EmacsFrame ew) | |||
| 486 | { | 345 | { |
| 487 | struct frame *f = ew->emacs_frame.frame; | 346 | struct frame *f = ew->emacs_frame.frame; |
| 488 | 347 | ||
| 489 | /* Don't do that: It confuses the check in change_frame_size_1 whether | ||
| 490 | the pixel size of the frame changed due to a change of the internal | ||
| 491 | border width. Bug#16736. */ | ||
| 492 | if (false) | ||
| 493 | { | ||
| 494 | struct x_output *x = f->output_data.x; | ||
| 495 | FRAME_PIXEL_HEIGHT (f) = ew->core.height + x->menubar_height; | ||
| 496 | FRAME_PIXEL_WIDTH (f) = ew->core.width; | ||
| 497 | } | ||
| 498 | |||
| 499 | f->internal_border_width = ew->emacs_frame.internal_border_width; | 348 | f->internal_border_width = ew->emacs_frame.internal_border_width; |
| 500 | } | 349 | } |
| 501 | 350 | ||
| @@ -504,6 +353,7 @@ update_from_various_frame_slots (EmacsFrame ew) | |||
| 504 | { | 353 | { |
| 505 | struct frame *f = ew->emacs_frame.frame; | 354 | struct frame *f = ew->emacs_frame.frame; |
| 506 | struct x_output *x = f->output_data.x; | 355 | struct x_output *x = f->output_data.x; |
| 356 | |||
| 507 | ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height; | 357 | ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height; |
| 508 | ew->core.width = FRAME_PIXEL_WIDTH (f); | 358 | ew->core.width = FRAME_PIXEL_WIDTH (f); |
| 509 | ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f); | 359 | ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f); |
| @@ -576,7 +426,10 @@ EmacsFrameResize (Widget widget) | |||
| 576 | 426 | ||
| 577 | frame_size_history_add | 427 | frame_size_history_add |
| 578 | (f, QEmacsFrameResize, width, height, | 428 | (f, QEmacsFrameResize, width, height, |
| 579 | list2 (make_number (ew->core.width), make_number (ew->core.height))); | 429 | list5 (make_number (ew->core.width), make_number (ew->core.height), |
| 430 | make_number (FRAME_TOP_MARGIN_HEIGHT (f)), | ||
| 431 | make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (f)), | ||
| 432 | make_number (2 * FRAME_INTERNAL_BORDER_WIDTH (f)))); | ||
| 580 | 433 | ||
| 581 | change_frame_size (f, width, height, 0, 1, 0, 1); | 434 | change_frame_size (f, width, height, 0, 1, 0, 1); |
| 582 | 435 | ||
| @@ -596,11 +449,12 @@ EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeome | |||
| 596 | 449 | ||
| 597 | if (mask & (CWWidth | CWHeight)) | 450 | if (mask & (CWWidth | CWHeight)) |
| 598 | { | 451 | { |
| 599 | round_size_to_char (ew, | 452 | if (!frame_resize_pixelwise) |
| 600 | (mask & CWWidth) ? request->width : ew->core.width, | 453 | round_size_to_char (ew, |
| 601 | ((mask & CWHeight) ? request->height | 454 | (mask & CWWidth) ? request->width : ew->core.width, |
| 602 | : ew->core.height), | 455 | ((mask & CWHeight) ? request->height |
| 603 | &ok_width, &ok_height); | 456 | : ew->core.height), |
| 457 | &ok_width, &ok_height); | ||
| 604 | if ((mask & CWWidth) && (ok_width != request->width)) | 458 | if ((mask & CWWidth) && (ok_width != request->width)) |
| 605 | { | 459 | { |
| 606 | result->request_mode |= CWWidth; | 460 | result->request_mode |= CWWidth; |