summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Lindgren <andlind@gmail.com>2016-03-22 20:18:33 +0100
committerAnders Lindgren <andlind@gmail.com>2016-03-22 20:18:33 +0100
commite643977b6b99466bfa872b61a4101d9937615876 (patch)
tree90ce4ea49ababc42cd60b468e80019797bd5091b
parent38a43f1a8f26f1ec8dbb9b2981f1d98f2b2bd228 (diff)
downloademacs-e643977b6b99466bfa872b61a4101d9937615876.tar.gz
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.
-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)
}
-/* True, if the menu bar should be hidden. */
-
static BOOL
ns_menu_bar_should_be_hidden (void)
+/* True, if the menu bar should be hidden. */
{
return !NILP (ns_auto_hide_menu_bar)
&& [NSApp respondsToSelector:@selector(setPresentationOptions:)];
}
-static CGFloat
-ns_menu_bar_height (NSScreen *screen)
-/* The height of the menu bar, if visible.
+struct EmacsMargins
+{
+ CGFloat top;
+ CGFloat bottom;
+ CGFloat left;
+ CGFloat right;
+};
- Note: Don't use this when fullscreen is enabled -- the screen
- sometimes includes, sometimes excludes the menu bar area. */
+
+static struct EmacsMargins
+ns_screen_margins (NSScreen *screen)
+/* The parts of SCREEN used by the operating system. */
{
- CGFloat res;
+ NSTRACE ("ns_screen_margins");
+
+ struct EmacsMargins margins;
+
+ NSRect screenFrame = [screen frame];
+ NSRect screenVisibleFrame = [screen visibleFrame];
+ /* Sometimes, visibleFrame isn't up-to-date with respect to a hidden
+ menu bar, check this explicitly. */
if (ns_menu_bar_should_be_hidden())
{
- res = 0;
+ margins.top = 0;
}
else
{
- NSRect screenFrame = [screen frame];
- NSRect screenVisibleFrame = [screen visibleFrame];
-
CGFloat frameTop = screenFrame.origin.y + screenFrame.size.height;
CGFloat visibleFrameTop = (screenVisibleFrame.origin.y
+ screenVisibleFrame.size.height);
- res = frameTop - visibleFrameTop;
+ margins.top = frameTop - visibleFrameTop;
+ }
+
+ {
+ CGFloat frameRight = screenFrame.origin.x + screenFrame.size.width;
+ CGFloat visibleFrameRight = (screenVisibleFrame.origin.x
+ + screenVisibleFrame.size.width);
+ margins.right = frameRight - visibleFrameRight;
+ }
+
+ margins.bottom = screenVisibleFrame.origin.y - screenFrame.origin.y;
+ margins.left = screenVisibleFrame.origin.x - screenFrame.origin.x;
+ NSTRACE_MSG ("left:%g right:%g top:%g bottom:%g",
+ margins.left,
+ margins.right,
+ margins.top,
+ margins.bottom);
+
+ return margins;
+}
+
+
+/* A screen margin between 1 and DOCK_IGNORE_LIMIT (inclusive) is
+ assumed to contain a hidden dock. OS X currently use 4 pixels for
+ this, however, to be future compatible, a larger value is used. */
+#define DOCK_IGNORE_LIMIT 6
+
+static struct EmacsMargins
+ns_screen_margins_ignoring_hidden_dock (NSScreen *screen)
+/* The parts of SCREEN used by the operating system, excluding the parts
+reserved for an hidden dock. */
+{
+ NSTRACE ("ns_screen_margins_ignoring_hidden_dock");
+
+ struct EmacsMargins margins = ns_screen_margins(screen);
+
+ /* OS X (currently) reserved 4 pixels along the edge where a hidden
+ dock is located. Unfortunately, it's not possible to find the
+ location and information about if the dock is hidden. Instead,
+ it is assumed that if the margin of an edge is less than
+ DOCK_IGNORE_LIMIT, it contains a hidden dock. */
+ if (margins.left <= DOCK_IGNORE_LIMIT)
+ {
+ margins.left = 0;
+ }
+ if (margins.right <= DOCK_IGNORE_LIMIT)
+ {
+ margins.right = 0;
+ }
+ if (margins.top <= DOCK_IGNORE_LIMIT)
+ {
+ margins.top = 0;
+ }
+ /* Note: This doesn't occur in current versions of OS X, but
+ included for completeness and future compatibility. */
+ if (margins.bottom <= DOCK_IGNORE_LIMIT)
+ {
+ margins.bottom = 0;
}
+ NSTRACE_MSG ("left:%g right:%g top:%g bottom:%g",
+ margins.left,
+ margins.right,
+ margins.top,
+ margins.bottom);
+
+ return margins;
+}
+
+
+static CGFloat
+ns_menu_bar_height (NSScreen *screen)
+/* The height of the menu bar, if visible.
+
+ Note: Don't use this when fullscreen is enabled -- the screen
+ sometimes includes, sometimes excludes the menu bar area. */
+{
+ struct EmacsMargins margins = ns_screen_margins(screen);
+
+ CGFloat res = margins.top;
+
NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res);
return res;
@@ -7867,9 +7954,10 @@ not_in_argv (NSString *arg)
// the menu-bar.
[super zoom:sender];
-#elsif 0
+#elif 0
// Native zoom done using the standard zoom animation, plus an
- // explicit resize to cover the full screen.
+ // explicit resize to cover the full screen, except the menu-bar and
+ // dock, if present.
[super zoom:sender];
// After the native zoom, resize the resulting frame to fill the
@@ -7889,6 +7977,9 @@ not_in_argv (NSString *arg)
NSTRACE_FSTYPE ("fullscreenState", fs_state);
NSRect sr = [screen frame];
+ struct EmacsMargins margins
+ = ns_screen_margins_ignoring_hidden_dock(screen);
+
NSRect wr = [self frame];
NSTRACE_RECT ("Rect after zoom", wr);
@@ -7897,15 +7988,15 @@ not_in_argv (NSString *arg)
if (fs_state == FULLSCREEN_MAXIMIZED
|| fs_state == FULLSCREEN_HEIGHT)
{
- newWr.origin.x = 0;
- newWr.size.height = sr.size.height - ns_menu_bar_height(screen);
+ newWr.origin.y = sr.origin.y + margins.bottom;
+ newWr.size.height = sr.size.height - margins.top - margins.bottom;
}
if (fs_state == FULLSCREEN_MAXIMIZED
|| fs_state == FULLSCREEN_WIDTH)
{
- newWr.origin.y = 0;
- newWr.size.width = sr.size.width;
+ newWr.origin.x = sr.origin.x + margins.left;
+ newWr.size.width = sr.size.width - margins.right - margins.left;
}
if (newWr.size.width != wr.size.width
@@ -7918,13 +8009,20 @@ not_in_argv (NSString *arg)
}
}
#else
- // Non-native zoom which is done instantaneously. The resulting frame
- // covers the entire screen, except the menu-bar, if present.
+ // Non-native zoom which is done instantaneously. The resulting
+ // frame covers the entire screen, except the menu-bar and dock, if
+ // present.
NSScreen * screen = [self screen];
if (screen != nil)
{
NSRect sr = [screen frame];
- sr.size.height -= ns_menu_bar_height (screen);
+ struct EmacsMargins margins
+ = ns_screen_margins_ignoring_hidden_dock(screen);
+
+ sr.size.height -= (margins.top + margins.bottom);
+ sr.size.width -= (margins.left + margins.right);
+ sr.origin.x += margins.left;
+ sr.origin.y += margins.bottom;
sr = [[self delegate] windowWillUseStandardFrame:self
defaultFrame:sr];