diff options
| author | Paul Eggert | 2016-03-23 11:24:28 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-03-23 11:24:28 -0700 |
| commit | 16e4bd52e3119d4905de02d33f1cc134498cb0b6 (patch) | |
| tree | 530e3fc934ef4c024889829fc744e46a2d81e7ed /src | |
| parent | 70c7a51d1410f446fd7e9a49aa370ecbed7941bb (diff) | |
| parent | e643977b6b99466bfa872b61a4101d9937615876 (diff) | |
| download | emacs-16e4bd52e3119d4905de02d33f1cc134498cb0b6.tar.gz emacs-16e4bd52e3119d4905de02d33f1cc134498cb0b6.zip | |
Merge from origin/emacs-25
e643977 Make `toggle-frame-maximized' respect the dock on OS X (bug#2...
38a43f1 Fix bug in displaying header line with a box face
Diffstat (limited to 'src')
| -rw-r--r-- | src/nsterm.m | 142 | ||||
| -rw-r--r-- | src/xdisp.c | 61 |
2 files changed, 167 insertions, 36 deletions
diff --git a/src/nsterm.m b/src/nsterm.m index b796193af77..4048ac46546 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -646,42 +646,129 @@ ns_release_autorelease_pool (void *pool) | |||
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | 648 | ||
| 649 | /* True, if the menu bar should be hidden. */ | ||
| 650 | |||
| 651 | static BOOL | 649 | static BOOL |
| 652 | ns_menu_bar_should_be_hidden (void) | 650 | ns_menu_bar_should_be_hidden (void) |
| 651 | /* True, if the menu bar should be hidden. */ | ||
| 653 | { | 652 | { |
| 654 | return !NILP (ns_auto_hide_menu_bar) | 653 | return !NILP (ns_auto_hide_menu_bar) |
| 655 | && [NSApp respondsToSelector:@selector(setPresentationOptions:)]; | 654 | && [NSApp respondsToSelector:@selector(setPresentationOptions:)]; |
| 656 | } | 655 | } |
| 657 | 656 | ||
| 658 | 657 | ||
| 659 | static CGFloat | 658 | struct EmacsMargins |
| 660 | ns_menu_bar_height (NSScreen *screen) | 659 | { |
| 661 | /* The height of the menu bar, if visible. | 660 | CGFloat top; |
| 661 | CGFloat bottom; | ||
| 662 | CGFloat left; | ||
| 663 | CGFloat right; | ||
| 664 | }; | ||
| 662 | 665 | ||
| 663 | Note: Don't use this when fullscreen is enabled -- the screen | 666 | |
| 664 | sometimes includes, sometimes excludes the menu bar area. */ | 667 | static struct EmacsMargins |
| 668 | ns_screen_margins (NSScreen *screen) | ||
| 669 | /* The parts of SCREEN used by the operating system. */ | ||
| 665 | { | 670 | { |
| 666 | CGFloat res; | 671 | NSTRACE ("ns_screen_margins"); |
| 672 | |||
| 673 | struct EmacsMargins margins; | ||
| 674 | |||
| 675 | NSRect screenFrame = [screen frame]; | ||
| 676 | NSRect screenVisibleFrame = [screen visibleFrame]; | ||
| 667 | 677 | ||
| 678 | /* Sometimes, visibleFrame isn't up-to-date with respect to a hidden | ||
| 679 | menu bar, check this explicitly. */ | ||
| 668 | if (ns_menu_bar_should_be_hidden()) | 680 | if (ns_menu_bar_should_be_hidden()) |
| 669 | { | 681 | { |
| 670 | res = 0; | 682 | margins.top = 0; |
| 671 | } | 683 | } |
| 672 | else | 684 | else |
| 673 | { | 685 | { |
| 674 | NSRect screenFrame = [screen frame]; | ||
| 675 | NSRect screenVisibleFrame = [screen visibleFrame]; | ||
| 676 | |||
| 677 | CGFloat frameTop = screenFrame.origin.y + screenFrame.size.height; | 686 | CGFloat frameTop = screenFrame.origin.y + screenFrame.size.height; |
| 678 | CGFloat visibleFrameTop = (screenVisibleFrame.origin.y | 687 | CGFloat visibleFrameTop = (screenVisibleFrame.origin.y |
| 679 | + screenVisibleFrame.size.height); | 688 | + screenVisibleFrame.size.height); |
| 680 | 689 | ||
| 681 | res = frameTop - visibleFrameTop; | 690 | margins.top = frameTop - visibleFrameTop; |
| 691 | } | ||
| 692 | |||
| 693 | { | ||
| 694 | CGFloat frameRight = screenFrame.origin.x + screenFrame.size.width; | ||
| 695 | CGFloat visibleFrameRight = (screenVisibleFrame.origin.x | ||
| 696 | + screenVisibleFrame.size.width); | ||
| 697 | margins.right = frameRight - visibleFrameRight; | ||
| 698 | } | ||
| 699 | |||
| 700 | margins.bottom = screenVisibleFrame.origin.y - screenFrame.origin.y; | ||
| 701 | margins.left = screenVisibleFrame.origin.x - screenFrame.origin.x; | ||
| 682 | 702 | ||
| 703 | NSTRACE_MSG ("left:%g right:%g top:%g bottom:%g", | ||
| 704 | margins.left, | ||
| 705 | margins.right, | ||
| 706 | margins.top, | ||
| 707 | margins.bottom); | ||
| 708 | |||
| 709 | return margins; | ||
| 710 | } | ||
| 711 | |||
| 712 | |||
| 713 | /* A screen margin between 1 and DOCK_IGNORE_LIMIT (inclusive) is | ||
| 714 | assumed to contain a hidden dock. OS X currently use 4 pixels for | ||
| 715 | this, however, to be future compatible, a larger value is used. */ | ||
| 716 | #define DOCK_IGNORE_LIMIT 6 | ||
| 717 | |||
| 718 | static struct EmacsMargins | ||
| 719 | ns_screen_margins_ignoring_hidden_dock (NSScreen *screen) | ||
| 720 | /* The parts of SCREEN used by the operating system, excluding the parts | ||
| 721 | reserved for an hidden dock. */ | ||
| 722 | { | ||
| 723 | NSTRACE ("ns_screen_margins_ignoring_hidden_dock"); | ||
| 724 | |||
| 725 | struct EmacsMargins margins = ns_screen_margins(screen); | ||
| 726 | |||
| 727 | /* OS X (currently) reserved 4 pixels along the edge where a hidden | ||
| 728 | dock is located. Unfortunately, it's not possible to find the | ||
| 729 | location and information about if the dock is hidden. Instead, | ||
| 730 | it is assumed that if the margin of an edge is less than | ||
| 731 | DOCK_IGNORE_LIMIT, it contains a hidden dock. */ | ||
| 732 | if (margins.left <= DOCK_IGNORE_LIMIT) | ||
| 733 | { | ||
| 734 | margins.left = 0; | ||
| 735 | } | ||
| 736 | if (margins.right <= DOCK_IGNORE_LIMIT) | ||
| 737 | { | ||
| 738 | margins.right = 0; | ||
| 739 | } | ||
| 740 | if (margins.top <= DOCK_IGNORE_LIMIT) | ||
| 741 | { | ||
| 742 | margins.top = 0; | ||
| 743 | } | ||
| 744 | /* Note: This doesn't occur in current versions of OS X, but | ||
| 745 | included for completeness and future compatibility. */ | ||
| 746 | if (margins.bottom <= DOCK_IGNORE_LIMIT) | ||
| 747 | { | ||
| 748 | margins.bottom = 0; | ||
| 683 | } | 749 | } |
| 684 | 750 | ||
| 751 | NSTRACE_MSG ("left:%g right:%g top:%g bottom:%g", | ||
| 752 | margins.left, | ||
| 753 | margins.right, | ||
| 754 | margins.top, | ||
| 755 | margins.bottom); | ||
| 756 | |||
| 757 | return margins; | ||
| 758 | } | ||
| 759 | |||
| 760 | |||
| 761 | static CGFloat | ||
| 762 | ns_menu_bar_height (NSScreen *screen) | ||
| 763 | /* The height of the menu bar, if visible. | ||
| 764 | |||
| 765 | Note: Don't use this when fullscreen is enabled -- the screen | ||
| 766 | sometimes includes, sometimes excludes the menu bar area. */ | ||
| 767 | { | ||
| 768 | struct EmacsMargins margins = ns_screen_margins(screen); | ||
| 769 | |||
| 770 | CGFloat res = margins.top; | ||
| 771 | |||
| 685 | NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res); | 772 | NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res); |
| 686 | 773 | ||
| 687 | return res; | 774 | return res; |
| @@ -7867,9 +7954,10 @@ not_in_argv (NSString *arg) | |||
| 7867 | // the menu-bar. | 7954 | // the menu-bar. |
| 7868 | [super zoom:sender]; | 7955 | [super zoom:sender]; |
| 7869 | 7956 | ||
| 7870 | #elsif 0 | 7957 | #elif 0 |
| 7871 | // Native zoom done using the standard zoom animation, plus an | 7958 | // Native zoom done using the standard zoom animation, plus an |
| 7872 | // explicit resize to cover the full screen. | 7959 | // explicit resize to cover the full screen, except the menu-bar and |
| 7960 | // dock, if present. | ||
| 7873 | [super zoom:sender]; | 7961 | [super zoom:sender]; |
| 7874 | 7962 | ||
| 7875 | // After the native zoom, resize the resulting frame to fill the | 7963 | // After the native zoom, resize the resulting frame to fill the |
| @@ -7889,6 +7977,9 @@ not_in_argv (NSString *arg) | |||
| 7889 | NSTRACE_FSTYPE ("fullscreenState", fs_state); | 7977 | NSTRACE_FSTYPE ("fullscreenState", fs_state); |
| 7890 | 7978 | ||
| 7891 | NSRect sr = [screen frame]; | 7979 | NSRect sr = [screen frame]; |
| 7980 | struct EmacsMargins margins | ||
| 7981 | = ns_screen_margins_ignoring_hidden_dock(screen); | ||
| 7982 | |||
| 7892 | NSRect wr = [self frame]; | 7983 | NSRect wr = [self frame]; |
| 7893 | NSTRACE_RECT ("Rect after zoom", wr); | 7984 | NSTRACE_RECT ("Rect after zoom", wr); |
| 7894 | 7985 | ||
| @@ -7897,15 +7988,15 @@ not_in_argv (NSString *arg) | |||
| 7897 | if (fs_state == FULLSCREEN_MAXIMIZED | 7988 | if (fs_state == FULLSCREEN_MAXIMIZED |
| 7898 | || fs_state == FULLSCREEN_HEIGHT) | 7989 | || fs_state == FULLSCREEN_HEIGHT) |
| 7899 | { | 7990 | { |
| 7900 | newWr.origin.x = 0; | 7991 | newWr.origin.y = sr.origin.y + margins.bottom; |
| 7901 | newWr.size.height = sr.size.height - ns_menu_bar_height(screen); | 7992 | newWr.size.height = sr.size.height - margins.top - margins.bottom; |
| 7902 | } | 7993 | } |
| 7903 | 7994 | ||
| 7904 | if (fs_state == FULLSCREEN_MAXIMIZED | 7995 | if (fs_state == FULLSCREEN_MAXIMIZED |
| 7905 | || fs_state == FULLSCREEN_WIDTH) | 7996 | || fs_state == FULLSCREEN_WIDTH) |
| 7906 | { | 7997 | { |
| 7907 | newWr.origin.y = 0; | 7998 | newWr.origin.x = sr.origin.x + margins.left; |
| 7908 | newWr.size.width = sr.size.width; | 7999 | newWr.size.width = sr.size.width - margins.right - margins.left; |
| 7909 | } | 8000 | } |
| 7910 | 8001 | ||
| 7911 | if (newWr.size.width != wr.size.width | 8002 | if (newWr.size.width != wr.size.width |
| @@ -7918,13 +8009,20 @@ not_in_argv (NSString *arg) | |||
| 7918 | } | 8009 | } |
| 7919 | } | 8010 | } |
| 7920 | #else | 8011 | #else |
| 7921 | // Non-native zoom which is done instantaneously. The resulting frame | 8012 | // Non-native zoom which is done instantaneously. The resulting |
| 7922 | // covers the entire screen, except the menu-bar, if present. | 8013 | // frame covers the entire screen, except the menu-bar and dock, if |
| 8014 | // present. | ||
| 7923 | NSScreen * screen = [self screen]; | 8015 | NSScreen * screen = [self screen]; |
| 7924 | if (screen != nil) | 8016 | if (screen != nil) |
| 7925 | { | 8017 | { |
| 7926 | NSRect sr = [screen frame]; | 8018 | NSRect sr = [screen frame]; |
| 7927 | sr.size.height -= ns_menu_bar_height (screen); | 8019 | struct EmacsMargins margins |
| 8020 | = ns_screen_margins_ignoring_hidden_dock(screen); | ||
| 8021 | |||
| 8022 | sr.size.height -= (margins.top + margins.bottom); | ||
| 8023 | sr.size.width -= (margins.left + margins.right); | ||
| 8024 | sr.origin.x += margins.left; | ||
| 8025 | sr.origin.y += margins.bottom; | ||
| 7928 | 8026 | ||
| 7929 | sr = [[self delegate] windowWillUseStandardFrame:self | 8027 | sr = [[self delegate] windowWillUseStandardFrame:self |
| 7930 | defaultFrame:sr]; | 8028 | defaultFrame:sr]; |
diff --git a/src/xdisp.c b/src/xdisp.c index 7dc99e1c283..254b97beb87 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -7229,18 +7229,21 @@ get_next_display_element (struct it *it) | |||
| 7229 | { | 7229 | { |
| 7230 | ptrdiff_t ignore; | 7230 | ptrdiff_t ignore; |
| 7231 | int next_face_id; | 7231 | int next_face_id; |
| 7232 | bool text_from_string = false; | ||
| 7233 | /* Normally, the next buffer location is stored in | ||
| 7234 | IT->current.pos... */ | ||
| 7232 | struct text_pos pos = it->current.pos; | 7235 | struct text_pos pos = it->current.pos; |
| 7233 | 7236 | ||
| 7234 | /* For a string from a display property, the next | 7237 | /* ...but for a string from a display property, the |
| 7235 | buffer position is stored in the 'position' | 7238 | next buffer position is stored in the 'position' |
| 7236 | member of the iteration stack slot below the | 7239 | member of the iteration stack slot below the |
| 7237 | current one, see handle_single_display_spec. By | 7240 | current one, see handle_single_display_spec. By |
| 7238 | contrast, it->current.pos was not yet updated | 7241 | contrast, it->current.pos was not yet updated to |
| 7239 | to point to that buffer position; that will | 7242 | point to that buffer position; that will happen |
| 7240 | happen in pop_it, after we finish displaying the | 7243 | in pop_it, after we finish displaying the current |
| 7241 | current string. Note that we already checked | 7244 | string. Note that we already checked above that |
| 7242 | above that it->sp is positive, so subtracting one | 7245 | it->sp is positive, so subtracting one from it is |
| 7243 | from it is safe. */ | 7246 | safe. */ |
| 7244 | if (it->from_disp_prop_p) | 7247 | if (it->from_disp_prop_p) |
| 7245 | { | 7248 | { |
| 7246 | int stackp = it->sp - 1; | 7249 | int stackp = it->sp - 1; |
| @@ -7249,19 +7252,49 @@ get_next_display_element (struct it *it) | |||
| 7249 | while (stackp >= 0 | 7252 | while (stackp >= 0 |
| 7250 | && STRINGP ((it->stack + stackp)->string)) | 7253 | && STRINGP ((it->stack + stackp)->string)) |
| 7251 | stackp--; | 7254 | stackp--; |
| 7252 | eassert (stackp >= 0); | 7255 | if (stackp < 0) |
| 7253 | pos = (it->stack + stackp)->position; | 7256 | { |
| 7257 | /* If no stack slot was found for iterating | ||
| 7258 | a buffer, we are displaying text from a | ||
| 7259 | string, most probably the mode line or | ||
| 7260 | the header line, and that string has a | ||
| 7261 | display string on some of its | ||
| 7262 | characters. */ | ||
| 7263 | text_from_string = true; | ||
| 7264 | pos = it->stack[it->sp - 1].position; | ||
| 7265 | } | ||
| 7266 | else | ||
| 7267 | pos = (it->stack + stackp)->position; | ||
| 7254 | } | 7268 | } |
| 7255 | else | 7269 | else |
| 7256 | INC_TEXT_POS (pos, it->multibyte_p); | 7270 | INC_TEXT_POS (pos, it->multibyte_p); |
| 7257 | 7271 | ||
| 7258 | if (CHARPOS (pos) >= ZV) | 7272 | if (text_from_string) |
| 7273 | { | ||
| 7274 | Lisp_Object base_string = it->stack[it->sp - 1].string; | ||
| 7275 | |||
| 7276 | if (CHARPOS (pos) >= SCHARS (base_string) - 1) | ||
| 7277 | it->end_of_box_run_p = true; | ||
| 7278 | else | ||
| 7279 | { | ||
| 7280 | next_face_id | ||
| 7281 | = face_at_string_position (it->w, base_string, | ||
| 7282 | CHARPOS (pos), 0, | ||
| 7283 | &ignore, face_id, false); | ||
| 7284 | it->end_of_box_run_p | ||
| 7285 | = (FACE_FROM_ID (it->f, next_face_id)->box | ||
| 7286 | == FACE_NO_BOX); | ||
| 7287 | } | ||
| 7288 | } | ||
| 7289 | else if (CHARPOS (pos) >= ZV) | ||
| 7259 | it->end_of_box_run_p = true; | 7290 | it->end_of_box_run_p = true; |
| 7260 | else | 7291 | else |
| 7261 | { | 7292 | { |
| 7262 | next_face_id = face_at_buffer_position | 7293 | next_face_id = |
| 7263 | (it->w, CHARPOS (pos), &ignore, | 7294 | face_at_buffer_position (it->w, CHARPOS (pos), &ignore, |
| 7264 | CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, false, -1); | 7295 | CHARPOS (pos) |
| 7296 | + TEXT_PROP_DISTANCE_LIMIT, | ||
| 7297 | false, -1); | ||
| 7265 | it->end_of_box_run_p | 7298 | it->end_of_box_run_p |
| 7266 | = (FACE_FROM_ID (it->f, next_face_id)->box | 7299 | = (FACE_FROM_ID (it->f, next_face_id)->box |
| 7267 | == FACE_NO_BOX); | 7300 | == FACE_NO_BOX); |