aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAnders Lindgren2016-03-22 20:18:33 +0100
committerAnders Lindgren2016-03-22 20:18:33 +0100
commite643977b6b99466bfa872b61a4101d9937615876 (patch)
tree90ce4ea49ababc42cd60b468e80019797bd5091b /src
parent38a43f1a8f26f1ec8dbb9b2981f1d98f2b2bd228 (diff)
downloademacs-e643977b6b99466bfa872b61a4101d9937615876.tar.gz
emacs-e643977b6b99466bfa872b61a4101d9937615876.zip
Make `toggle-frame-maximized' respect the dock on OS X (bug#22988).
* src/nsterm.m (ns_screen_margins): New function. (ns_screen_margins_ignoring_hidden_dock): New function. (ns_menu_bar_height): Reimplement in terms of `ns_screen_margins'. ([EmacsWindow zoom:]): Take all screen margins (except those originating from a hidden dock) into account.
Diffstat (limited to 'src')
-rw-r--r--src/nsterm.m142
1 files changed, 120 insertions, 22 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
651static BOOL 649static BOOL
652ns_menu_bar_should_be_hidden (void) 650ns_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
659static CGFloat 658struct EmacsMargins
660ns_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. */ 667static struct EmacsMargins
668ns_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
718static struct EmacsMargins
719ns_screen_margins_ignoring_hidden_dock (NSScreen *screen)
720/* The parts of SCREEN used by the operating system, excluding the parts
721reserved 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
761static CGFloat
762ns_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];