diff options
| author | Bastien | 2017-07-03 09:06:29 +0200 |
|---|---|---|
| committer | Bastien | 2017-07-03 09:06:29 +0200 |
| commit | 5ca1888fe670aee7febd4d42665d7372ab2ffebc (patch) | |
| tree | 1f7f8d8a7580e556fc83cf3a6aaeec567b33a090 /src/frame.c | |
| parent | 20e006ffee41062f1b551a92c24d9edc53cd0f56 (diff) | |
| parent | 1b4f0a92ff3505ef9a465b9b391756e3a73a6443 (diff) | |
| download | emacs-5ca1888fe670aee7febd4d42665d7372ab2ffebc.tar.gz emacs-5ca1888fe670aee7febd4d42665d7372ab2ffebc.zip | |
Merge branch 'master' into scratch/org-mode-merge
Diffstat (limited to 'src/frame.c')
| -rw-r--r-- | src/frame.c | 783 |
1 files changed, 630 insertions, 153 deletions
diff --git a/src/frame.c b/src/frame.c index 4d17a071dc7..1e5e4bbdb48 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -328,8 +328,8 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size, | |||
| 328 | * frame_windows_min_size: | 328 | * frame_windows_min_size: |
| 329 | * | 329 | * |
| 330 | * Return the minimum number of lines (columns if HORIZONTAL is non-nil) | 330 | * Return the minimum number of lines (columns if HORIZONTAL is non-nil) |
| 331 | * of FRAME. If PIXELWISE is non-nil, return the minimum height (width) | 331 | * of FRAME. If PIXELWISE is non-nil, return the minimum inner height |
| 332 | * in pixels. | 332 | * (width) of FRAME in pixels. |
| 333 | * | 333 | * |
| 334 | * This value is calculated by the function `frame-windows-min-size' in | 334 | * This value is calculated by the function `frame-windows-min-size' in |
| 335 | * window.el unless the `min-height' (`min-width' if HORIZONTAL is | 335 | * window.el unless the `min-height' (`min-width' if HORIZONTAL is |
| @@ -341,7 +341,7 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size, | |||
| 341 | * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil). | 341 | * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil). |
| 342 | * With IGNORE non-nil the values of these variables are ignored. | 342 | * With IGNORE non-nil the values of these variables are ignored. |
| 343 | * | 343 | * |
| 344 | * In either case never return a value less than 1. | 344 | * In either case, never return a value less than 1. |
| 345 | */ | 345 | */ |
| 346 | static int | 346 | static int |
| 347 | frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, | 347 | frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, |
| @@ -373,46 +373,173 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, | |||
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | 375 | ||
| 376 | /* Make sure windows sizes of frame F are OK. new_width and new_height | 376 | #ifdef HAVE_WINDOW_SYSTEM |
| 377 | are in pixels. A value of -1 means no change is requested for that | 377 | /** |
| 378 | size (but the frame may still have to be resized to accommodate | 378 | * keep_ratio: |
| 379 | windows with their minimum sizes). This can either issue a request | 379 | * |
| 380 | to resize the frame externally (via x_set_window_size), to resize the | 380 | * Preserve ratios of frame F which usually happens after its parent |
| 381 | frame internally (via resize_frame_windows) or do nothing at all. | 381 | * frame P got resized. OLD_WIDTH, OLD_HEIGHT specifies the old native |
| 382 | * size of F's parent, NEW_WIDTH and NEW_HEIGHT its new size. | ||
| 383 | * | ||
| 384 | * Adjust F's width if F's 'keep_ratio' parameter is non-nil and, if | ||
| 385 | * it is a cons, its car is not 'height-only'. Adjust F's height if F's | ||
| 386 | * 'keep_ratio' parameter is non-nil and, if it is a cons, its car | ||
| 387 | * is not 'width-only'. | ||
| 388 | * | ||
| 389 | * Adjust F's left position if F's 'keep_ratio' parameter is non-nil | ||
| 390 | * and, if its is a cons, its cdr is non-nil and not 'top-only'. Adjust | ||
| 391 | * F's top position if F's 'keep_ratio' parameter is non-nil and, if | ||
| 392 | * its is a cons, its cdr is non-nil and not 'left-only'. | ||
| 393 | * | ||
| 394 | * Note that when positional adjustment is requested but the size of F | ||
| 395 | * should remain unaltered in the corresponding direction, this routine | ||
| 396 | * tries to constrain F to its parent frame - something which usually | ||
| 397 | * happens when the parent frame shrinks. This means, however, that | ||
| 398 | * when the parent frame is re-enlarged later, the child's original | ||
| 399 | * position will not get restored to its pre-shrinking value. | ||
| 400 | * | ||
| 401 | * This routine is currently useful for child frames only. It might be | ||
| 402 | * eventually useful when moving non-child frames between monitors with | ||
| 403 | * different resolutions. | ||
| 404 | */ | ||
| 405 | static void | ||
| 406 | keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height, | ||
| 407 | int new_width, int new_height) | ||
| 408 | { | ||
| 409 | Lisp_Object keep_ratio = get_frame_param (f, Qkeep_ratio); | ||
| 410 | |||
| 411 | |||
| 412 | if (!NILP (keep_ratio)) | ||
| 413 | { | ||
| 414 | double width_factor = (double)new_width / (double)old_width; | ||
| 415 | double height_factor = (double)new_height / (double)old_height; | ||
| 416 | int pixel_width, pixel_height, pos_x, pos_y; | ||
| 417 | |||
| 418 | if (!CONSP (keep_ratio) || !NILP (Fcdr (keep_ratio))) | ||
| 419 | { | ||
| 420 | if (CONSP (keep_ratio) && EQ (Fcdr (keep_ratio), Qtop_only)) | ||
| 421 | pos_x = f->left_pos; | ||
| 422 | else | ||
| 423 | { | ||
| 424 | pos_x = (int)(f->left_pos * width_factor + 0.5); | ||
| 382 | 425 | ||
| 383 | The argument INHIBIT can assume the following values: | 426 | if (CONSP (keep_ratio) |
| 427 | && (NILP (Fcar (keep_ratio)) | ||
| 428 | || EQ (Fcar (keep_ratio), Qheight_only)) | ||
| 429 | && p->pixel_width - f->pixel_width < pos_x) | ||
| 430 | { | ||
| 431 | int p_f_width = p->pixel_width - f->pixel_width; | ||
| 384 | 432 | ||
| 385 | 0 means to unconditionally call x_set_window_size even if sizes | 433 | if (p_f_width <= 0) |
| 386 | apparently do not change. Fx_create_frame uses this to pass the | 434 | pos_x = 0; |
| 387 | initial size to the window manager. | 435 | else |
| 436 | pos_x = (int)(p_f_width * width_factor * 0.5 + 0.5); | ||
| 437 | } | ||
| 388 | 438 | ||
| 389 | 1 means to call x_set_window_size if the outer frame size really | 439 | f->left_pos = pos_x; |
| 390 | changes. Fset_frame_size, Fset_frame_height, ... use this. | 440 | } |
| 391 | 441 | ||
| 392 | 2 means to call x_set_window_size provided frame_inhibit_resize | 442 | if (CONSP (keep_ratio) && EQ (Fcdr (keep_ratio), Qleft_only)) |
| 393 | allows it. The menu and tool bar code use this ("3" won't work | 443 | pos_y = f->top_pos; |
| 394 | here in general because menu and tool bar are often not counted in | 444 | else |
| 395 | the frame's text height). | 445 | { |
| 446 | pos_y = (int)(f->top_pos * height_factor + 0.5); | ||
| 447 | |||
| 448 | if (CONSP (keep_ratio) | ||
| 449 | && (NILP (Fcar (keep_ratio)) | ||
| 450 | || EQ (Fcar (keep_ratio), Qwidth_only)) | ||
| 451 | && p->pixel_height - f->pixel_height < pos_y) | ||
| 452 | /* When positional adjustment was requested and the | ||
| 453 | width of F should remain unaltered, try to constrain | ||
| 454 | F to its parent. This means that when the parent | ||
| 455 | frame is enlarged later the child's original position | ||
| 456 | won't get restored. */ | ||
| 457 | { | ||
| 458 | int p_f_height = p->pixel_height - f->pixel_height; | ||
| 396 | 459 | ||
| 397 | 3 means call x_set_window_size if window minimum sizes must be | 460 | if (p_f_height <= 0) |
| 398 | preserved or frame_inhibit_resize allows it. x_set_left_fringe, | 461 | pos_y = 0; |
| 399 | x_set_scroll_bar_width, x_new_font ... use (or should use) this. | 462 | else |
| 463 | pos_y = (int)(p_f_height * height_factor * 0.5 + 0.5); | ||
| 464 | } | ||
| 400 | 465 | ||
| 401 | 4 means call x_set_window_size only if window minimum sizes must be | 466 | f->top_pos = pos_y; |
| 402 | preserved. x_set_right_divider_width, x_set_border_width and the | 467 | } |
| 403 | code responsible for wrapping the tool bar use this. | ||
| 404 | 468 | ||
| 405 | 5 means to never call x_set_window_size. change_frame_size uses | 469 | x_set_offset (f, pos_x, pos_y, -1); |
| 406 | this. | 470 | } |
| 407 | 471 | ||
| 408 | Note that even when x_set_window_size is not called, individual | 472 | if (!CONSP (keep_ratio) || !NILP (Fcar (keep_ratio))) |
| 409 | windows may have to be resized (via `window--sanitize-window-sizes') | 473 | { |
| 410 | in order to support minimum size constraints. | 474 | if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qheight_only)) |
| 475 | pixel_width = -1; | ||
| 476 | else | ||
| 477 | { | ||
| 478 | pixel_width = (int)(f->pixel_width * width_factor + 0.5); | ||
| 479 | pixel_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width); | ||
| 480 | } | ||
| 411 | 481 | ||
| 412 | PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the | 482 | if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qwidth_only)) |
| 413 | symbol of the parameter changed (like `menu-bar-lines', `font', ...). | 483 | pixel_height = -1; |
| 414 | This is passed on to frame_inhibit_resize to let the latter decide on | 484 | else |
| 415 | a case-by-case basis whether the frame may be resized externally. */ | 485 | { |
| 486 | pixel_height = (int)(f->pixel_height * height_factor + 0.5); | ||
| 487 | pixel_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height); | ||
| 488 | } | ||
| 489 | |||
| 490 | adjust_frame_size (f, pixel_width, pixel_height, 1, 0, | ||
| 491 | Qkeep_ratio); | ||
| 492 | } | ||
| 493 | } | ||
| 494 | } | ||
| 495 | #endif | ||
| 496 | |||
| 497 | |||
| 498 | /** | ||
| 499 | * adjust_frame_size: | ||
| 500 | * | ||
| 501 | * Adjust size of frame F. NEW_WIDTH and NEW_HEIGHT specify the new | ||
| 502 | * text size of F in pixels. A value of -1 means no change is requested | ||
| 503 | * for that direction (but the frame may still have to be resized to | ||
| 504 | * accommodate windows with their minimum sizes). This can either issue | ||
| 505 | * a request to resize the frame externally (via x_set_window_size), to | ||
| 506 | * resize the frame internally (via resize_frame_windows) or do nothing | ||
| 507 | * at all. | ||
| 508 | * | ||
| 509 | * The argument INHIBIT can assume the following values: | ||
| 510 | * | ||
| 511 | * 0 means to unconditionally call x_set_window_size even if sizes | ||
| 512 | * apparently do not change. Fx_create_frame uses this to pass the | ||
| 513 | * initial size to the window manager. | ||
| 514 | * | ||
| 515 | * 1 means to call x_set_window_size if the native frame size really | ||
| 516 | * changes. Fset_frame_size, Fset_frame_height, ... use this. | ||
| 517 | * | ||
| 518 | * 2 means to call x_set_window_size provided frame_inhibit_resize | ||
| 519 | * allows it. The menu and tool bar code use this ("3" won't work | ||
| 520 | * here in general because menu and tool bar are often not counted in | ||
| 521 | * the frame's text height). | ||
| 522 | * | ||
| 523 | * 3 means call x_set_window_size if window minimum sizes must be | ||
| 524 | * preserved or frame_inhibit_resize allows it. x_set_left_fringe, | ||
| 525 | * x_set_scroll_bar_width, x_new_font ... use (or should use) this. | ||
| 526 | * | ||
| 527 | * 4 means call x_set_window_size only if window minimum sizes must be | ||
| 528 | * preserved. x_set_right_divider_width, x_set_border_width and the | ||
| 529 | * code responsible for wrapping the tool bar use this. | ||
| 530 | * | ||
| 531 | * 5 means to never call x_set_window_size. change_frame_size uses | ||
| 532 | * this. | ||
| 533 | * | ||
| 534 | * Note that even when x_set_window_size is not called, individual | ||
| 535 | * windows may have to be resized (via `window--sanitize-window-sizes') | ||
| 536 | * in order to support minimum size constraints. | ||
| 537 | * | ||
| 538 | * PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the | ||
| 539 | * symbol of the parameter changed (like `menu-bar-lines', `font', ...). | ||
| 540 | * This is passed on to frame_inhibit_resize to let the latter decide on | ||
| 541 | * a case-by-case basis whether the frame may be resized externally. | ||
| 542 | */ | ||
| 416 | void | 543 | void |
| 417 | adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, | 544 | adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, |
| 418 | bool pretend, Lisp_Object parameter) | 545 | bool pretend, Lisp_Object parameter) |
| @@ -636,6 +763,18 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, | |||
| 636 | || new_pixel_height != old_pixel_height); | 763 | || new_pixel_height != old_pixel_height); |
| 637 | 764 | ||
| 638 | unblock_input (); | 765 | unblock_input (); |
| 766 | |||
| 767 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 768 | { | ||
| 769 | /* Adjust size of F's child frames. */ | ||
| 770 | Lisp_Object frames, frame1; | ||
| 771 | |||
| 772 | FOR_EACH_FRAME (frames, frame1) | ||
| 773 | if (FRAME_PARENT_FRAME (XFRAME (frame1)) == f) | ||
| 774 | keep_ratio (XFRAME (frame1), f, old_pixel_width, old_pixel_height, | ||
| 775 | new_pixel_width, new_pixel_height); | ||
| 776 | } | ||
| 777 | #endif | ||
| 639 | } | 778 | } |
| 640 | 779 | ||
| 641 | /* Allocate basically initialized frame. */ | 780 | /* Allocate basically initialized frame. */ |
| @@ -684,6 +823,7 @@ make_frame (bool mini_p) | |||
| 684 | f->horizontal_scroll_bars = false; | 823 | f->horizontal_scroll_bars = false; |
| 685 | f->want_fullscreen = FULLSCREEN_NONE; | 824 | f->want_fullscreen = FULLSCREEN_NONE; |
| 686 | f->undecorated = false; | 825 | f->undecorated = false; |
| 826 | f->no_special_glyphs = false; | ||
| 687 | #ifndef HAVE_NTGUI | 827 | #ifndef HAVE_NTGUI |
| 688 | f->override_redirect = false; | 828 | f->override_redirect = false; |
| 689 | #endif | 829 | #endif |
| @@ -2004,8 +2144,101 @@ The functions are run with one argument, the frame to be deleted. */) | |||
| 2004 | { | 2144 | { |
| 2005 | return delete_frame (frame, !NILP (force) ? Qt : Qnil); | 2145 | return delete_frame (frame, !NILP (force) ? Qt : Qnil); |
| 2006 | } | 2146 | } |
| 2007 | |||
| 2008 | 2147 | ||
| 2148 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 2149 | /** | ||
| 2150 | * frame_internal_border_part: | ||
| 2151 | * | ||
| 2152 | * Return part of internal border the coordinates X and Y relative to | ||
| 2153 | * frame F are on. Return nil if the coordinates are not on the | ||
| 2154 | * internal border of F. | ||
| 2155 | * | ||
| 2156 | * Return one of INTERNAL_BORDER_LEFT_EDGE, INTERNAL_BORDER_TOP_EDGE, | ||
| 2157 | * INTERNAL_BORDER_RIGHT_EDGE or INTERNAL_BORDER_BOTTOM_EDGE when the | ||
| 2158 | * mouse cursor is on the corresponding border with an offset of at | ||
| 2159 | * least one canonical character height from that border's edges. | ||
| 2160 | * | ||
| 2161 | * If no border part could be found this way, return one of | ||
| 2162 | * INTERNAL_BORDER_TOP_LEFT_CORNER, INTERNAL_BORDER_TOP_RIGHT_CORNER, | ||
| 2163 | * INTERNAL_BORDER_BOTTOM_LEFT_CORNER or | ||
| 2164 | * INTERNAL_BORDER_BOTTOM_RIGHT_CORNER to indicate that the mouse is in | ||
| 2165 | * one of the corresponding corners. This means that for very small | ||
| 2166 | * frames an `edge' return value is preferred. | ||
| 2167 | */ | ||
| 2168 | enum internal_border_part | ||
| 2169 | frame_internal_border_part (struct frame *f, int x, int y) | ||
| 2170 | { | ||
| 2171 | int border = FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 2172 | int offset = FRAME_LINE_HEIGHT (f); | ||
| 2173 | int width = FRAME_PIXEL_WIDTH (f); | ||
| 2174 | int height = FRAME_PIXEL_HEIGHT (f); | ||
| 2175 | enum internal_border_part part = INTERNAL_BORDER_NONE; | ||
| 2176 | |||
| 2177 | if (offset < border) | ||
| 2178 | /* For very wide borders make offset at least as large as | ||
| 2179 | border. */ | ||
| 2180 | offset = border; | ||
| 2181 | |||
| 2182 | if (offset < x && x < width - offset) | ||
| 2183 | /* Top or bottom border. */ | ||
| 2184 | { | ||
| 2185 | if (0 <= y && y <= border) | ||
| 2186 | part = INTERNAL_BORDER_TOP_EDGE; | ||
| 2187 | else if (height - border <= y && y <= height) | ||
| 2188 | part = INTERNAL_BORDER_BOTTOM_EDGE; | ||
| 2189 | } | ||
| 2190 | else if (offset < y && y < height - offset) | ||
| 2191 | /* Left or right border. */ | ||
| 2192 | { | ||
| 2193 | if (0 <= x && x <= border) | ||
| 2194 | part = INTERNAL_BORDER_LEFT_EDGE; | ||
| 2195 | else if (width - border <= x && x <= width) | ||
| 2196 | part = INTERNAL_BORDER_RIGHT_EDGE; | ||
| 2197 | } | ||
| 2198 | else | ||
| 2199 | { | ||
| 2200 | /* An edge. */ | ||
| 2201 | int half_width = width / 2; | ||
| 2202 | int half_height = height / 2; | ||
| 2203 | |||
| 2204 | if (0 <= x && x <= border) | ||
| 2205 | { | ||
| 2206 | /* A left edge. */ | ||
| 2207 | if (0 <= y && y <= half_height) | ||
| 2208 | part = INTERNAL_BORDER_TOP_LEFT_CORNER; | ||
| 2209 | else if (half_height < y && y <= height) | ||
| 2210 | part = INTERNAL_BORDER_BOTTOM_LEFT_CORNER; | ||
| 2211 | } | ||
| 2212 | else if (width - border <= x && x <= width) | ||
| 2213 | { | ||
| 2214 | /* A right edge. */ | ||
| 2215 | if (0 <= y && y <= half_height) | ||
| 2216 | part = INTERNAL_BORDER_TOP_RIGHT_CORNER; | ||
| 2217 | else if (half_height < y && y <= height) | ||
| 2218 | part = INTERNAL_BORDER_BOTTOM_RIGHT_CORNER; | ||
| 2219 | } | ||
| 2220 | else if (0 <= y && y <= border) | ||
| 2221 | { | ||
| 2222 | /* A top edge. */ | ||
| 2223 | if (0 <= x && x <= half_width) | ||
| 2224 | part = INTERNAL_BORDER_TOP_LEFT_CORNER; | ||
| 2225 | else if (half_width < x && x <= width) | ||
| 2226 | part = INTERNAL_BORDER_TOP_RIGHT_CORNER; | ||
| 2227 | } | ||
| 2228 | else if (height - border <= y && y <= height) | ||
| 2229 | { | ||
| 2230 | /* A bottom edge. */ | ||
| 2231 | if (0 <= x && x <= half_width) | ||
| 2232 | part = INTERNAL_BORDER_BOTTOM_LEFT_CORNER; | ||
| 2233 | else if (half_width < x && x <= width) | ||
| 2234 | part = INTERNAL_BORDER_BOTTOM_RIGHT_CORNER; | ||
| 2235 | } | ||
| 2236 | } | ||
| 2237 | |||
| 2238 | return part; | ||
| 2239 | } | ||
| 2240 | #endif | ||
| 2241 | |||
| 2009 | /* Return mouse position in character cell units. */ | 2242 | /* Return mouse position in character cell units. */ |
| 2010 | 2243 | ||
| 2011 | DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0, | 2244 | DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0, |
| @@ -2962,49 +3195,47 @@ For a terminal screen, the value is always 1. */) | |||
| 2962 | return make_number (1); | 3195 | return make_number (1); |
| 2963 | } | 3196 | } |
| 2964 | 3197 | ||
| 2965 | DEFUN ("frame-pixel-height", Fframe_pixel_height, | 3198 | DEFUN ("frame-native-width", Fframe_native_width, |
| 2966 | Sframe_pixel_height, 0, 1, 0, | 3199 | Sframe_native_width, 0, 1, 0, |
| 2967 | doc: /* Return a FRAME's height in pixels. | 3200 | doc: /* Return FRAME's native width in pixels. |
| 2968 | If FRAME is omitted or nil, the selected frame is used. The exact value | 3201 | For a terminal frame, the result really gives the width in characters. |
| 2969 | of the result depends on the window-system and toolkit in use: | 3202 | If FRAME is omitted or nil, the selected frame is used. */) |
| 2970 | |||
| 2971 | In the Gtk+ version of Emacs, it includes only any window (including | ||
| 2972 | the minibuffer or echo area), mode line, and header line. It does not | ||
| 2973 | include the tool bar or menu bar. | ||
| 2974 | |||
| 2975 | With other graphical versions, it also includes the tool bar and the | ||
| 2976 | menu bar. | ||
| 2977 | |||
| 2978 | For a text terminal, it includes the menu bar. In this case, the | ||
| 2979 | result is really in characters rather than pixels (i.e., is identical | ||
| 2980 | to `frame-height'). */) | ||
| 2981 | (Lisp_Object frame) | 3203 | (Lisp_Object frame) |
| 2982 | { | 3204 | { |
| 2983 | struct frame *f = decode_any_frame (frame); | 3205 | struct frame *f = decode_any_frame (frame); |
| 2984 | 3206 | ||
| 2985 | #ifdef HAVE_WINDOW_SYSTEM | 3207 | #ifdef HAVE_WINDOW_SYSTEM |
| 2986 | if (FRAME_WINDOW_P (f)) | 3208 | if (FRAME_WINDOW_P (f)) |
| 2987 | return make_number (FRAME_PIXEL_HEIGHT (f)); | 3209 | return make_number (FRAME_PIXEL_WIDTH (f)); |
| 2988 | else | 3210 | else |
| 2989 | #endif | 3211 | #endif |
| 2990 | return make_number (FRAME_TOTAL_LINES (f)); | 3212 | return make_number (FRAME_TOTAL_COLS (f)); |
| 2991 | } | 3213 | } |
| 2992 | 3214 | ||
| 2993 | DEFUN ("frame-pixel-width", Fframe_pixel_width, | 3215 | DEFUN ("frame-native-height", Fframe_native_height, |
| 2994 | Sframe_pixel_width, 0, 1, 0, | 3216 | Sframe_native_height, 0, 1, 0, |
| 2995 | doc: /* Return FRAME's width in pixels. | 3217 | doc: /* Return FRAME's native height in pixels. |
| 2996 | For a terminal frame, the result really gives the width in characters. | 3218 | If FRAME is omitted or nil, the selected frame is used. The exact value |
| 2997 | If FRAME is omitted or nil, the selected frame is used. */) | 3219 | of the result depends on the window-system and toolkit in use: |
| 3220 | |||
| 3221 | In the Gtk+ and NS versions, it includes only any window (including the | ||
| 3222 | minibuffer or echo area), mode line, and header line. It does not | ||
| 3223 | include the tool bar or menu bar. With other graphical versions, it may | ||
| 3224 | also include the tool bar and the menu bar. | ||
| 3225 | |||
| 3226 | For a text terminal, it includes the menu bar. In this case, the | ||
| 3227 | result is really in characters rather than pixels (i.e., is identical | ||
| 3228 | to `frame-height'). */) | ||
| 2998 | (Lisp_Object frame) | 3229 | (Lisp_Object frame) |
| 2999 | { | 3230 | { |
| 3000 | struct frame *f = decode_any_frame (frame); | 3231 | struct frame *f = decode_any_frame (frame); |
| 3001 | 3232 | ||
| 3002 | #ifdef HAVE_WINDOW_SYSTEM | 3233 | #ifdef HAVE_WINDOW_SYSTEM |
| 3003 | if (FRAME_WINDOW_P (f)) | 3234 | if (FRAME_WINDOW_P (f)) |
| 3004 | return make_number (FRAME_PIXEL_WIDTH (f)); | 3235 | return make_number (FRAME_PIXEL_HEIGHT (f)); |
| 3005 | else | 3236 | else |
| 3006 | #endif | 3237 | #endif |
| 3007 | return make_number (FRAME_TOTAL_COLS (f)); | 3238 | return make_number (FRAME_TOTAL_LINES (f)); |
| 3008 | } | 3239 | } |
| 3009 | 3240 | ||
| 3010 | DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width, | 3241 | DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width, |
| @@ -3087,8 +3318,8 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0, | |||
| 3087 | return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame))); | 3318 | return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame))); |
| 3088 | } | 3319 | } |
| 3089 | 3320 | ||
| 3090 | DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0, | 3321 | DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0, |
| 3091 | doc: /* Return border width of FRAME in pixels. */) | 3322 | doc: /* Return width of FRAME's internal border in pixels. */) |
| 3092 | (Lisp_Object frame) | 3323 | (Lisp_Object frame) |
| 3093 | { | 3324 | { |
| 3094 | return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame))); | 3325 | return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame))); |
| @@ -3224,7 +3455,6 @@ bottom edge of FRAME's display. */) | |||
| 3224 | 3455 | ||
| 3225 | return Qt; | 3456 | return Qt; |
| 3226 | } | 3457 | } |
| 3227 | |||
| 3228 | 3458 | ||
| 3229 | /*********************************************************************** | 3459 | /*********************************************************************** |
| 3230 | Frame Parameters | 3460 | Frame Parameters |
| @@ -3289,10 +3519,193 @@ static const struct frame_parm_table frame_parms[] = | |||
| 3289 | {"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus)}, | 3519 | {"no-accept-focus", SYMBOL_INDEX (Qno_accept_focus)}, |
| 3290 | {"z-group", SYMBOL_INDEX (Qz_group)}, | 3520 | {"z-group", SYMBOL_INDEX (Qz_group)}, |
| 3291 | {"override-redirect", SYMBOL_INDEX (Qoverride_redirect)}, | 3521 | {"override-redirect", SYMBOL_INDEX (Qoverride_redirect)}, |
| 3522 | {"no-special-glyphs", SYMBOL_INDEX (Qno_special_glyphs)}, | ||
| 3292 | }; | 3523 | }; |
| 3293 | 3524 | ||
| 3294 | #ifdef HAVE_WINDOW_SYSTEM | 3525 | #ifdef HAVE_WINDOW_SYSTEM |
| 3295 | 3526 | ||
| 3527 | /* Enumeration type for switch in frame_float. */ | ||
| 3528 | enum frame_float_type | ||
| 3529 | { | ||
| 3530 | FRAME_FLOAT_WIDTH, | ||
| 3531 | FRAME_FLOAT_HEIGHT, | ||
| 3532 | FRAME_FLOAT_LEFT, | ||
| 3533 | FRAME_FLOAT_TOP | ||
| 3534 | }; | ||
| 3535 | |||
| 3536 | /** | ||
| 3537 | * frame_float: | ||
| 3538 | * | ||
| 3539 | * Process the value VAL of the float type frame parameter 'width', | ||
| 3540 | * 'height', 'left', or 'top' specified via a frame_float_type | ||
| 3541 | * enumeration type WHAT for frame F. Such parameters relate the outer | ||
| 3542 | * size or position of F to the size of the F's display or parent frame | ||
| 3543 | * which have to be both available in some way. | ||
| 3544 | * | ||
| 3545 | * The return value is a size or position value in pixels. VAL must be | ||
| 3546 | * in the range 0.0 to 1.0 where a width/height of 0.0 means to return 0 | ||
| 3547 | * and 1.0 means to return the full width/height of the display/parent. | ||
| 3548 | * For positions, 0.0 means position in the left/top corner of the | ||
| 3549 | * display/parent while 1.0 means to position at the right/bottom corner | ||
| 3550 | * of the display/parent frame. | ||
| 3551 | * | ||
| 3552 | * Set PARENT_DONE and OUTER_DONE to avoid recalculation of the outer | ||
| 3553 | * size or parent or display attributes when more float parameters are | ||
| 3554 | * calculated in a row: -1 means not processed yet, 0 means processing | ||
| 3555 | * failed, 1 means processing succeeded. | ||
| 3556 | * | ||
| 3557 | * Return DEFAULT_VALUE when processing fails for whatever reason with | ||
| 3558 | * one exception: When calculating F's outer edges fails (probably | ||
| 3559 | * because F has not been created yet) return the difference between F's | ||
| 3560 | * native and text size. | ||
| 3561 | */ | ||
| 3562 | static int | ||
| 3563 | frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what, | ||
| 3564 | int *parent_done, int *outer_done, int default_value) | ||
| 3565 | { | ||
| 3566 | double d_val = XFLOAT_DATA (val); | ||
| 3567 | |||
| 3568 | if (d_val < 0.0 || d_val > 1.0) | ||
| 3569 | /* Invalid VAL. */ | ||
| 3570 | return default_value; | ||
| 3571 | else | ||
| 3572 | { | ||
| 3573 | static unsigned parent_width, parent_height; | ||
| 3574 | static int parent_left, parent_top; | ||
| 3575 | static unsigned outer_minus_text_width, outer_minus_text_height; | ||
| 3576 | struct frame *p = FRAME_PARENT_FRAME (f); | ||
| 3577 | |||
| 3578 | if (*parent_done == 1) | ||
| 3579 | ; | ||
| 3580 | else if (p) | ||
| 3581 | { | ||
| 3582 | parent_width = FRAME_PIXEL_WIDTH (p); | ||
| 3583 | parent_height = FRAME_PIXEL_HEIGHT (p); | ||
| 3584 | *parent_done = 1; | ||
| 3585 | } | ||
| 3586 | else | ||
| 3587 | { | ||
| 3588 | if (*parent_done == 0) | ||
| 3589 | /* No workarea available. */ | ||
| 3590 | return default_value; | ||
| 3591 | else if (*parent_done == -1) | ||
| 3592 | { | ||
| 3593 | Lisp_Object monitor_attributes; | ||
| 3594 | Lisp_Object workarea; | ||
| 3595 | Lisp_Object frame; | ||
| 3596 | |||
| 3597 | XSETFRAME (frame, f); | ||
| 3598 | monitor_attributes = Fcar (call1 (Qdisplay_monitor_attributes_list, frame)); | ||
| 3599 | if (NILP (monitor_attributes)) | ||
| 3600 | { | ||
| 3601 | /* No monitor attributes available. */ | ||
| 3602 | *parent_done = 0; | ||
| 3603 | |||
| 3604 | return default_value; | ||
| 3605 | } | ||
| 3606 | |||
| 3607 | workarea = Fcdr (Fassq (Qworkarea, monitor_attributes)); | ||
| 3608 | if (NILP (workarea)) | ||
| 3609 | { | ||
| 3610 | /* No workarea available. */ | ||
| 3611 | *parent_done = 0; | ||
| 3612 | |||
| 3613 | return default_value; | ||
| 3614 | } | ||
| 3615 | |||
| 3616 | /* Workarea available. */ | ||
| 3617 | parent_left = XINT (Fnth (make_number (0), workarea)); | ||
| 3618 | parent_top = XINT (Fnth (make_number (1), workarea)); | ||
| 3619 | parent_width = XINT (Fnth (make_number (2), workarea)); | ||
| 3620 | parent_height = XINT (Fnth (make_number (3), workarea)); | ||
| 3621 | *parent_done = 1; | ||
| 3622 | } | ||
| 3623 | } | ||
| 3624 | |||
| 3625 | if (*outer_done == 1) | ||
| 3626 | ; | ||
| 3627 | else if (FRAME_UNDECORATED (f)) | ||
| 3628 | { | ||
| 3629 | outer_minus_text_width | ||
| 3630 | = FRAME_PIXEL_WIDTH (f) - FRAME_TEXT_WIDTH (f); | ||
| 3631 | outer_minus_text_height | ||
| 3632 | = FRAME_PIXEL_HEIGHT (f) - FRAME_TEXT_HEIGHT (f); | ||
| 3633 | *outer_done = 1; | ||
| 3634 | } | ||
| 3635 | else if (*outer_done == 0) | ||
| 3636 | /* No outer size available. */ | ||
| 3637 | return default_value; | ||
| 3638 | else if (*outer_done == -1) | ||
| 3639 | { | ||
| 3640 | Lisp_Object frame, outer_edges; | ||
| 3641 | |||
| 3642 | XSETFRAME (frame, f); | ||
| 3643 | outer_edges = call2 (Qframe_edges, frame, Qouter_edges); | ||
| 3644 | |||
| 3645 | if (!NILP (outer_edges)) | ||
| 3646 | { | ||
| 3647 | outer_minus_text_width | ||
| 3648 | = (XINT (Fnth (make_number (2), outer_edges)) | ||
| 3649 | - XINT (Fnth (make_number (0), outer_edges)) | ||
| 3650 | - FRAME_TEXT_WIDTH (f)); | ||
| 3651 | outer_minus_text_height | ||
| 3652 | = (XINT (Fnth (make_number (3), outer_edges)) | ||
| 3653 | - XINT (Fnth (make_number (1), outer_edges)) | ||
| 3654 | - FRAME_TEXT_HEIGHT (f)); | ||
| 3655 | } | ||
| 3656 | else | ||
| 3657 | { | ||
| 3658 | /* If we can't get any outer edges, proceed as if the frame | ||
| 3659 | were undecorated. */ | ||
| 3660 | outer_minus_text_width | ||
| 3661 | = FRAME_PIXEL_WIDTH (f) - FRAME_TEXT_WIDTH (f); | ||
| 3662 | outer_minus_text_height | ||
| 3663 | = FRAME_PIXEL_HEIGHT (f) - FRAME_TEXT_HEIGHT (f); | ||
| 3664 | } | ||
| 3665 | |||
| 3666 | *outer_done = 1; | ||
| 3667 | } | ||
| 3668 | |||
| 3669 | switch (what) | ||
| 3670 | { | ||
| 3671 | case FRAME_FLOAT_WIDTH: | ||
| 3672 | return parent_width * d_val - outer_minus_text_width; | ||
| 3673 | |||
| 3674 | case FRAME_FLOAT_HEIGHT: | ||
| 3675 | return parent_height * d_val - outer_minus_text_height; | ||
| 3676 | |||
| 3677 | case FRAME_FLOAT_LEFT: | ||
| 3678 | { | ||
| 3679 | int rest_width = (parent_width | ||
| 3680 | - FRAME_TEXT_WIDTH (f) | ||
| 3681 | - outer_minus_text_width); | ||
| 3682 | |||
| 3683 | if (p) | ||
| 3684 | return (rest_width <= 0 ? 0 : d_val * rest_width); | ||
| 3685 | else | ||
| 3686 | return (rest_width <= 0 | ||
| 3687 | ? parent_left | ||
| 3688 | : parent_left + d_val * rest_width); | ||
| 3689 | } | ||
| 3690 | case FRAME_FLOAT_TOP: | ||
| 3691 | { | ||
| 3692 | int rest_height = (parent_height | ||
| 3693 | - FRAME_TEXT_HEIGHT (f) | ||
| 3694 | - outer_minus_text_height); | ||
| 3695 | |||
| 3696 | if (p) | ||
| 3697 | return (rest_height <= 0 ? 0 : d_val * rest_height); | ||
| 3698 | else | ||
| 3699 | return (rest_height <= 0 | ||
| 3700 | ? parent_top | ||
| 3701 | : parent_top + d_val * rest_height); | ||
| 3702 | } | ||
| 3703 | default: | ||
| 3704 | emacs_abort (); | ||
| 3705 | } | ||
| 3706 | } | ||
| 3707 | } | ||
| 3708 | |||
| 3296 | /* Change the parameters of frame F as specified by ALIST. | 3709 | /* Change the parameters of frame F as specified by ALIST. |
| 3297 | If a parameter is not specially recognized, do nothing special; | 3710 | If a parameter is not specially recognized, do nothing special; |
| 3298 | otherwise call the `x_set_...' function for that parameter. | 3711 | otherwise call the `x_set_...' function for that parameter. |
| @@ -3302,7 +3715,8 @@ static const struct frame_parm_table frame_parms[] = | |||
| 3302 | void | 3715 | void |
| 3303 | x_set_frame_parameters (struct frame *f, Lisp_Object alist) | 3716 | x_set_frame_parameters (struct frame *f, Lisp_Object alist) |
| 3304 | { | 3717 | { |
| 3305 | Lisp_Object tail; | 3718 | Lisp_Object tail, frame; |
| 3719 | |||
| 3306 | 3720 | ||
| 3307 | /* If both of these parameters are present, it's more efficient to | 3721 | /* If both of these parameters are present, it's more efficient to |
| 3308 | set them both at once. So we wait until we've looked at the | 3722 | set them both at once. So we wait until we've looked at the |
| @@ -3327,7 +3741,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3327 | #ifdef HAVE_X_WINDOWS | 3741 | #ifdef HAVE_X_WINDOWS |
| 3328 | bool icon_left_no_change = 0, icon_top_no_change = 0; | 3742 | bool icon_left_no_change = 0, icon_top_no_change = 0; |
| 3329 | #endif | 3743 | #endif |
| 3744 | int parent_done = -1, outer_done = -1; | ||
| 3330 | 3745 | ||
| 3746 | XSETFRAME (frame, f); | ||
| 3331 | for (size = 0, tail = alist; CONSP (tail); tail = XCDR (tail)) | 3747 | for (size = 0, tail = alist; CONSP (tail); tail = XCDR (tail)) |
| 3332 | size++; | 3748 | size++; |
| 3333 | CHECK_LIST_END (tail, alist); | 3749 | CHECK_LIST_END (tail, alist); |
| @@ -3388,6 +3804,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3388 | else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels) | 3804 | else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels) |
| 3389 | && RANGED_INTEGERP (0, XCDR (val), INT_MAX)) | 3805 | && RANGED_INTEGERP (0, XCDR (val), INT_MAX)) |
| 3390 | width = XFASTINT (XCDR (val)); | 3806 | width = XFASTINT (XCDR (val)); |
| 3807 | else if (FLOATP (val)) | ||
| 3808 | width = frame_float (f, val, FRAME_FLOAT_WIDTH, &parent_done, | ||
| 3809 | &outer_done, -1); | ||
| 3391 | } | 3810 | } |
| 3392 | else if (EQ (prop, Qheight)) | 3811 | else if (EQ (prop, Qheight)) |
| 3393 | { | 3812 | { |
| @@ -3396,6 +3815,9 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3396 | else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels) | 3815 | else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels) |
| 3397 | && RANGED_INTEGERP (0, XCDR (val), INT_MAX)) | 3816 | && RANGED_INTEGERP (0, XCDR (val), INT_MAX)) |
| 3398 | height = XFASTINT (XCDR (val)); | 3817 | height = XFASTINT (XCDR (val)); |
| 3818 | else if (FLOATP (val)) | ||
| 3819 | height = frame_float (f, val, FRAME_FLOAT_HEIGHT, &parent_done, | ||
| 3820 | &outer_done, -1); | ||
| 3399 | } | 3821 | } |
| 3400 | else if (EQ (prop, Qtop)) | 3822 | else if (EQ (prop, Qtop)) |
| 3401 | top = val; | 3823 | top = val; |
| @@ -3472,105 +3894,100 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3472 | Don't set these parameters unless they actually differ from the | 3894 | Don't set these parameters unless they actually differ from the |
| 3473 | window's current parameters; the window may not actually exist | 3895 | window's current parameters; the window may not actually exist |
| 3474 | yet. */ | 3896 | yet. */ |
| 3475 | { | 3897 | if ((width != -1 && width != FRAME_TEXT_WIDTH (f)) |
| 3476 | Lisp_Object frame; | 3898 | || (height != -1 && height != FRAME_TEXT_HEIGHT (f))) |
| 3477 | 3899 | /* We could consider checking f->after_make_frame here, but I | |
| 3478 | XSETFRAME (frame, f); | 3900 | don't have the faintest idea why the following is needed at |
| 3479 | 3901 | all. With the old setting it can get a Heisenbug when | |
| 3480 | if ((width != -1 && width != FRAME_TEXT_WIDTH (f)) | 3902 | EmacsFrameResize intermittently provokes a delayed |
| 3481 | || (height != -1 && height != FRAME_TEXT_HEIGHT (f))) | 3903 | change_frame_size in the middle of adjust_frame_size. */ |
| 3482 | /* We could consider checking f->after_make_frame here, but I | 3904 | /** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/ |
| 3483 | don't have the faintest idea why the following is needed at | 3905 | adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters); |
| 3484 | all. With the old setting it can get a Heisenbug when | 3906 | |
| 3485 | EmacsFrameResize intermittently provokes a delayed | 3907 | if ((!NILP (left) || !NILP (top)) |
| 3486 | change_frame_size in the middle of adjust_frame_size. */ | 3908 | && ! (left_no_change && top_no_change) |
| 3487 | /** || (f->can_x_set_window_size && (f->new_height || f->new_width))) **/ | 3909 | && ! (NUMBERP (left) && XINT (left) == f->left_pos |
| 3488 | adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters); | 3910 | && NUMBERP (top) && XINT (top) == f->top_pos)) |
| 3489 | 3911 | { | |
| 3490 | if ((!NILP (left) || !NILP (top)) | 3912 | int leftpos = 0; |
| 3491 | && ! (left_no_change && top_no_change) | 3913 | int toppos = 0; |
| 3492 | && ! (NUMBERP (left) && XINT (left) == f->left_pos | ||
| 3493 | && NUMBERP (top) && XINT (top) == f->top_pos)) | ||
| 3494 | { | ||
| 3495 | int leftpos = 0; | ||
| 3496 | int toppos = 0; | ||
| 3497 | 3914 | ||
| 3498 | /* Record the signs. */ | 3915 | /* Record the signs. */ |
| 3499 | f->size_hint_flags &= ~ (XNegative | YNegative); | 3916 | f->size_hint_flags &= ~ (XNegative | YNegative); |
| 3500 | if (EQ (left, Qminus)) | 3917 | if (EQ (left, Qminus)) |
| 3501 | f->size_hint_flags |= XNegative; | 3918 | f->size_hint_flags |= XNegative; |
| 3502 | else if (TYPE_RANGED_INTEGERP (int, left)) | 3919 | else if (TYPE_RANGED_INTEGERP (int, left)) |
| 3503 | { | 3920 | { |
| 3504 | leftpos = XINT (left); | 3921 | leftpos = XINT (left); |
| 3505 | if (leftpos < 0) | 3922 | if (leftpos < 0) |
| 3506 | f->size_hint_flags |= XNegative; | ||
| 3507 | } | ||
| 3508 | else if (CONSP (left) && EQ (XCAR (left), Qminus) | ||
| 3509 | && CONSP (XCDR (left)) | ||
| 3510 | && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX)) | ||
| 3511 | { | ||
| 3512 | leftpos = - XINT (XCAR (XCDR (left))); | ||
| 3513 | f->size_hint_flags |= XNegative; | 3923 | f->size_hint_flags |= XNegative; |
| 3514 | } | 3924 | } |
| 3515 | else if (CONSP (left) && EQ (XCAR (left), Qplus) | 3925 | else if (CONSP (left) && EQ (XCAR (left), Qminus) |
| 3516 | && CONSP (XCDR (left)) | 3926 | && CONSP (XCDR (left)) |
| 3517 | && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left)))) | 3927 | && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX)) |
| 3518 | { | 3928 | { |
| 3519 | leftpos = XINT (XCAR (XCDR (left))); | 3929 | leftpos = - XINT (XCAR (XCDR (left))); |
| 3520 | } | 3930 | f->size_hint_flags |= XNegative; |
| 3931 | } | ||
| 3932 | else if (CONSP (left) && EQ (XCAR (left), Qplus) | ||
| 3933 | && CONSP (XCDR (left)) | ||
| 3934 | && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left)))) | ||
| 3935 | leftpos = XINT (XCAR (XCDR (left))); | ||
| 3936 | else if (FLOATP (left)) | ||
| 3937 | leftpos = frame_float (f, left, FRAME_FLOAT_LEFT, &parent_done, | ||
| 3938 | &outer_done, 0); | ||
| 3521 | 3939 | ||
| 3522 | if (EQ (top, Qminus)) | 3940 | if (EQ (top, Qminus)) |
| 3523 | f->size_hint_flags |= YNegative; | 3941 | f->size_hint_flags |= YNegative; |
| 3524 | else if (TYPE_RANGED_INTEGERP (int, top)) | 3942 | else if (TYPE_RANGED_INTEGERP (int, top)) |
| 3525 | { | 3943 | { |
| 3526 | toppos = XINT (top); | 3944 | toppos = XINT (top); |
| 3527 | if (toppos < 0) | 3945 | if (toppos < 0) |
| 3528 | f->size_hint_flags |= YNegative; | ||
| 3529 | } | ||
| 3530 | else if (CONSP (top) && EQ (XCAR (top), Qminus) | ||
| 3531 | && CONSP (XCDR (top)) | ||
| 3532 | && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX)) | ||
| 3533 | { | ||
| 3534 | toppos = - XINT (XCAR (XCDR (top))); | ||
| 3535 | f->size_hint_flags |= YNegative; | 3946 | f->size_hint_flags |= YNegative; |
| 3536 | } | 3947 | } |
| 3537 | else if (CONSP (top) && EQ (XCAR (top), Qplus) | 3948 | else if (CONSP (top) && EQ (XCAR (top), Qminus) |
| 3538 | && CONSP (XCDR (top)) | 3949 | && CONSP (XCDR (top)) |
| 3539 | && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top)))) | 3950 | && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX)) |
| 3540 | { | 3951 | { |
| 3541 | toppos = XINT (XCAR (XCDR (top))); | 3952 | toppos = - XINT (XCAR (XCDR (top))); |
| 3542 | } | 3953 | f->size_hint_flags |= YNegative; |
| 3543 | 3954 | } | |
| 3955 | else if (CONSP (top) && EQ (XCAR (top), Qplus) | ||
| 3956 | && CONSP (XCDR (top)) | ||
| 3957 | && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top)))) | ||
| 3958 | toppos = XINT (XCAR (XCDR (top))); | ||
| 3959 | else if (FLOATP (top)) | ||
| 3960 | toppos = frame_float (f, top, FRAME_FLOAT_TOP, &parent_done, | ||
| 3961 | &outer_done, 0); | ||
| 3544 | 3962 | ||
| 3545 | /* Store the numeric value of the position. */ | 3963 | /* Store the numeric value of the position. */ |
| 3546 | f->top_pos = toppos; | 3964 | f->top_pos = toppos; |
| 3547 | f->left_pos = leftpos; | 3965 | f->left_pos = leftpos; |
| 3548 | 3966 | ||
| 3549 | f->win_gravity = NorthWestGravity; | 3967 | f->win_gravity = NorthWestGravity; |
| 3550 | 3968 | ||
| 3551 | /* Actually set that position, and convert to absolute. */ | 3969 | /* Actually set that position, and convert to absolute. */ |
| 3552 | x_set_offset (f, leftpos, toppos, -1); | 3970 | x_set_offset (f, leftpos, toppos, -1); |
| 3553 | } | 3971 | } |
| 3554 | 3972 | ||
| 3555 | if (fullscreen_change) | 3973 | if (fullscreen_change) |
| 3556 | { | 3974 | { |
| 3557 | Lisp_Object old_value = get_frame_param (f, Qfullscreen); | 3975 | Lisp_Object old_value = get_frame_param (f, Qfullscreen); |
| 3558 | 3976 | ||
| 3559 | frame_size_history_add | 3977 | frame_size_history_add |
| 3560 | (f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen)); | 3978 | (f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen)); |
| 3561 | 3979 | ||
| 3562 | store_frame_param (f, Qfullscreen, fullscreen); | 3980 | store_frame_param (f, Qfullscreen, fullscreen); |
| 3563 | if (!EQ (fullscreen, old_value)) | 3981 | if (!EQ (fullscreen, old_value)) |
| 3564 | x_set_fullscreen (f, fullscreen, old_value); | 3982 | x_set_fullscreen (f, fullscreen, old_value); |
| 3565 | } | 3983 | } |
| 3566 | 3984 | ||
| 3567 | 3985 | ||
| 3568 | #ifdef HAVE_X_WINDOWS | 3986 | #ifdef HAVE_X_WINDOWS |
| 3569 | if ((!NILP (icon_left) || !NILP (icon_top)) | 3987 | if ((!NILP (icon_left) || !NILP (icon_top)) |
| 3570 | && ! (icon_left_no_change && icon_top_no_change)) | 3988 | && ! (icon_left_no_change && icon_top_no_change)) |
| 3571 | x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); | 3989 | x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); |
| 3572 | #endif /* HAVE_X_WINDOWS */ | 3990 | #endif /* HAVE_X_WINDOWS */ |
| 3573 | } | ||
| 3574 | 3991 | ||
| 3575 | SAFE_FREE (); | 3992 | SAFE_FREE (); |
| 3576 | } | 3993 | } |
| @@ -3990,7 +4407,6 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | |||
| 3990 | adjust_frame_glyphs (f); | 4407 | adjust_frame_glyphs (f); |
| 3991 | SET_FRAME_GARBAGED (f); | 4408 | SET_FRAME_GARBAGED (f); |
| 3992 | } | 4409 | } |
| 3993 | |||
| 3994 | } | 4410 | } |
| 3995 | 4411 | ||
| 3996 | void | 4412 | void |
| @@ -4204,6 +4620,22 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | |||
| 4204 | return; | 4620 | return; |
| 4205 | } | 4621 | } |
| 4206 | 4622 | ||
| 4623 | |||
| 4624 | /** | ||
| 4625 | * x_set_no_special_glyphs: | ||
| 4626 | * | ||
| 4627 | * Set frame F's `no-special-glyphs' parameter which, if non-nil, | ||
| 4628 | * suppresses the display of truncation and continuation glyphs | ||
| 4629 | * outside fringes. | ||
| 4630 | */ | ||
| 4631 | void | ||
| 4632 | x_set_no_special_glyphs (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) | ||
| 4633 | { | ||
| 4634 | if (!EQ (new_value, old_value)) | ||
| 4635 | FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (new_value); | ||
| 4636 | } | ||
| 4637 | |||
| 4638 | |||
| 4207 | #ifndef HAVE_NS | 4639 | #ifndef HAVE_NS |
| 4208 | 4640 | ||
| 4209 | /* Non-zero if mouse is grabbed on DPYINFO | 4641 | /* Non-zero if mouse is grabbed on DPYINFO |
| @@ -4759,6 +5191,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x | |||
| 4759 | Lisp_Object height, width, user_size, top, left, user_position; | 5191 | Lisp_Object height, width, user_size, top, left, user_position; |
| 4760 | long window_prompting = 0; | 5192 | long window_prompting = 0; |
| 4761 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); | 5193 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 5194 | int parent_done = -1, outer_done = -1; | ||
| 4762 | 5195 | ||
| 4763 | /* Default values if we fall through. | 5196 | /* Default values if we fall through. |
| 4764 | Actually, if that happens we should get | 5197 | Actually, if that happens we should get |
| @@ -4823,6 +5256,21 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x | |||
| 4823 | f->inhibit_horizontal_resize = true; | 5256 | f->inhibit_horizontal_resize = true; |
| 4824 | *x_width = XINT (XCDR (width)); | 5257 | *x_width = XINT (XCDR (width)); |
| 4825 | } | 5258 | } |
| 5259 | else if (FLOATP (width)) | ||
| 5260 | { | ||
| 5261 | double d_width = XFLOAT_DATA (width); | ||
| 5262 | |||
| 5263 | if (d_width < 0.0 || d_width > 1.0) | ||
| 5264 | xsignal1 (Qargs_out_of_range, width); | ||
| 5265 | else | ||
| 5266 | { | ||
| 5267 | int new_width = frame_float (f, width, FRAME_FLOAT_WIDTH, | ||
| 5268 | &parent_done, &outer_done, -1); | ||
| 5269 | |||
| 5270 | if (new_width > -1) | ||
| 5271 | SET_FRAME_WIDTH (f, new_width); | ||
| 5272 | } | ||
| 5273 | } | ||
| 4826 | else | 5274 | else |
| 4827 | { | 5275 | { |
| 4828 | CHECK_NUMBER (width); | 5276 | CHECK_NUMBER (width); |
| @@ -4845,6 +5293,21 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x | |||
| 4845 | f->inhibit_vertical_resize = true; | 5293 | f->inhibit_vertical_resize = true; |
| 4846 | *x_height = XINT (XCDR (height)); | 5294 | *x_height = XINT (XCDR (height)); |
| 4847 | } | 5295 | } |
| 5296 | else if (FLOATP (height)) | ||
| 5297 | { | ||
| 5298 | double d_height = XFLOAT_DATA (height); | ||
| 5299 | |||
| 5300 | if (d_height < 0.0 || d_height > 1.0) | ||
| 5301 | xsignal1 (Qargs_out_of_range, height); | ||
| 5302 | else | ||
| 5303 | { | ||
| 5304 | int new_height = frame_float (f, height, FRAME_FLOAT_HEIGHT, | ||
| 5305 | &parent_done, &outer_done, -1); | ||
| 5306 | |||
| 5307 | if (new_height > -1) | ||
| 5308 | SET_FRAME_HEIGHT (f, new_height); | ||
| 5309 | } | ||
| 5310 | } | ||
| 4848 | else | 5311 | else |
| 4849 | { | 5312 | { |
| 4850 | CHECK_NUMBER (height); | 5313 | CHECK_NUMBER (height); |
| @@ -4885,6 +5348,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x | |||
| 4885 | { | 5348 | { |
| 4886 | f->top_pos = XINT (XCAR (XCDR (top))); | 5349 | f->top_pos = XINT (XCAR (XCDR (top))); |
| 4887 | } | 5350 | } |
| 5351 | else if (FLOATP (top)) | ||
| 5352 | f->top_pos = frame_float (f, top, FRAME_FLOAT_TOP, &parent_done, | ||
| 5353 | &outer_done, 0); | ||
| 4888 | else if (EQ (top, Qunbound)) | 5354 | else if (EQ (top, Qunbound)) |
| 4889 | f->top_pos = 0; | 5355 | f->top_pos = 0; |
| 4890 | else | 5356 | else |
| @@ -4913,6 +5379,9 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x | |||
| 4913 | { | 5379 | { |
| 4914 | f->left_pos = XINT (XCAR (XCDR (left))); | 5380 | f->left_pos = XINT (XCAR (XCDR (left))); |
| 4915 | } | 5381 | } |
| 5382 | else if (FLOATP (left)) | ||
| 5383 | f->left_pos = frame_float (f, left, FRAME_FLOAT_LEFT, &parent_done, | ||
| 5384 | &outer_done, 0); | ||
| 4916 | else if (EQ (left, Qunbound)) | 5385 | else if (EQ (left, Qunbound)) |
| 4917 | f->left_pos = 0; | 5386 | f->left_pos = 0; |
| 4918 | else | 5387 | else |
| @@ -5071,12 +5540,14 @@ syms_of_frame (void) | |||
| 5071 | DEFSYM (Qframep, "framep"); | 5540 | DEFSYM (Qframep, "framep"); |
| 5072 | DEFSYM (Qframe_live_p, "frame-live-p"); | 5541 | DEFSYM (Qframe_live_p, "frame-live-p"); |
| 5073 | DEFSYM (Qframe_windows_min_size, "frame-windows-min-size"); | 5542 | DEFSYM (Qframe_windows_min_size, "frame-windows-min-size"); |
| 5543 | DEFSYM (Qdisplay_monitor_attributes_list, "display-monitor-attributes-list"); | ||
| 5074 | DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total"); | 5544 | DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total"); |
| 5075 | DEFSYM (Qexplicit_name, "explicit-name"); | 5545 | DEFSYM (Qexplicit_name, "explicit-name"); |
| 5076 | DEFSYM (Qheight, "height"); | 5546 | DEFSYM (Qheight, "height"); |
| 5077 | DEFSYM (Qicon, "icon"); | 5547 | DEFSYM (Qicon, "icon"); |
| 5078 | DEFSYM (Qminibuffer, "minibuffer"); | 5548 | DEFSYM (Qminibuffer, "minibuffer"); |
| 5079 | DEFSYM (Qundecorated, "undecorated"); | 5549 | DEFSYM (Qundecorated, "undecorated"); |
| 5550 | DEFSYM (Qno_special_glyphs, "no-special-glyphs"); | ||
| 5080 | DEFSYM (Qparent_frame, "parent-frame"); | 5551 | DEFSYM (Qparent_frame, "parent-frame"); |
| 5081 | DEFSYM (Qskip_taskbar, "skip-taskbar"); | 5552 | DEFSYM (Qskip_taskbar, "skip-taskbar"); |
| 5082 | DEFSYM (Qno_focus_on_map, "no-focus-on-map"); | 5553 | DEFSYM (Qno_focus_on_map, "no-focus-on-map"); |
| @@ -5129,6 +5600,7 @@ syms_of_frame (void) | |||
| 5129 | DEFSYM (Qframes, "frames"); | 5600 | DEFSYM (Qframes, "frames"); |
| 5130 | DEFSYM (Qsource, "source"); | 5601 | DEFSYM (Qsource, "source"); |
| 5131 | 5602 | ||
| 5603 | DEFSYM (Qframe_edges, "frame-edges"); | ||
| 5132 | DEFSYM (Qouter_edges, "outer-edges"); | 5604 | DEFSYM (Qouter_edges, "outer-edges"); |
| 5133 | DEFSYM (Qouter_position, "outer-position"); | 5605 | DEFSYM (Qouter_position, "outer-position"); |
| 5134 | DEFSYM (Qouter_size, "outer-size"); | 5606 | DEFSYM (Qouter_size, "outer-size"); |
| @@ -5220,6 +5692,11 @@ syms_of_frame (void) | |||
| 5220 | DEFSYM (Qmin_width, "min-width"); | 5692 | DEFSYM (Qmin_width, "min-width"); |
| 5221 | DEFSYM (Qmin_height, "min-height"); | 5693 | DEFSYM (Qmin_height, "min-height"); |
| 5222 | DEFSYM (Qmouse_wheel_frame, "mouse-wheel-frame"); | 5694 | DEFSYM (Qmouse_wheel_frame, "mouse-wheel-frame"); |
| 5695 | DEFSYM (Qkeep_ratio, "keep-ratio"); | ||
| 5696 | DEFSYM (Qwidth_only, "width-only"); | ||
| 5697 | DEFSYM (Qheight_only, "height-only"); | ||
| 5698 | DEFSYM (Qleft_only, "left-only"); | ||
| 5699 | DEFSYM (Qtop_only, "top-only"); | ||
| 5223 | 5700 | ||
| 5224 | { | 5701 | { |
| 5225 | int i; | 5702 | int i; |
| @@ -5564,8 +6041,8 @@ Gtk+ tooltips are not used) and on Windows. */); | |||
| 5564 | defsubr (&Smodify_frame_parameters); | 6041 | defsubr (&Smodify_frame_parameters); |
| 5565 | defsubr (&Sframe_char_height); | 6042 | defsubr (&Sframe_char_height); |
| 5566 | defsubr (&Sframe_char_width); | 6043 | defsubr (&Sframe_char_width); |
| 5567 | defsubr (&Sframe_pixel_height); | 6044 | defsubr (&Sframe_native_height); |
| 5568 | defsubr (&Sframe_pixel_width); | 6045 | defsubr (&Sframe_native_width); |
| 5569 | defsubr (&Sframe_text_cols); | 6046 | defsubr (&Sframe_text_cols); |
| 5570 | defsubr (&Sframe_text_lines); | 6047 | defsubr (&Sframe_text_lines); |
| 5571 | defsubr (&Sframe_total_cols); | 6048 | defsubr (&Sframe_total_cols); |
| @@ -5575,7 +6052,7 @@ Gtk+ tooltips are not used) and on Windows. */); | |||
| 5575 | defsubr (&Sscroll_bar_width); | 6052 | defsubr (&Sscroll_bar_width); |
| 5576 | defsubr (&Sscroll_bar_height); | 6053 | defsubr (&Sscroll_bar_height); |
| 5577 | defsubr (&Sfringe_width); | 6054 | defsubr (&Sfringe_width); |
| 5578 | defsubr (&Sborder_width); | 6055 | defsubr (&Sframe_internal_border_width); |
| 5579 | defsubr (&Sright_divider_width); | 6056 | defsubr (&Sright_divider_width); |
| 5580 | defsubr (&Sbottom_divider_width); | 6057 | defsubr (&Sbottom_divider_width); |
| 5581 | defsubr (&Stool_bar_pixel_width); | 6058 | defsubr (&Stool_bar_pixel_width); |