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.
This commit is contained in:
parent
38a43f1a8f
commit
e643977b6b
1 changed files with 127 additions and 29 deletions
154
src/nsterm.m
154
src/nsterm.m
|
@ -646,16 +646,118 @@ Free a pool and temporary objects it refers to (callable from C)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* True, if the menu bar should be hidden. */
|
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
ns_menu_bar_should_be_hidden (void)
|
ns_menu_bar_should_be_hidden (void)
|
||||||
|
/* True, if the menu bar should be hidden. */
|
||||||
{
|
{
|
||||||
return !NILP (ns_auto_hide_menu_bar)
|
return !NILP (ns_auto_hide_menu_bar)
|
||||||
&& [NSApp respondsToSelector:@selector(setPresentationOptions:)];
|
&& [NSApp respondsToSelector:@selector(setPresentationOptions:)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct EmacsMargins
|
||||||
|
{
|
||||||
|
CGFloat top;
|
||||||
|
CGFloat bottom;
|
||||||
|
CGFloat left;
|
||||||
|
CGFloat right;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct EmacsMargins
|
||||||
|
ns_screen_margins (NSScreen *screen)
|
||||||
|
/* The parts of SCREEN used by the operating system. */
|
||||||
|
{
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
margins.top = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CGFloat frameTop = screenFrame.origin.y + screenFrame.size.height;
|
||||||
|
CGFloat visibleFrameTop = (screenVisibleFrame.origin.y
|
||||||
|
+ screenVisibleFrame.size.height);
|
||||||
|
|
||||||
|
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
|
static CGFloat
|
||||||
ns_menu_bar_height (NSScreen *screen)
|
ns_menu_bar_height (NSScreen *screen)
|
||||||
/* The height of the menu bar, if visible.
|
/* The height of the menu bar, if visible.
|
||||||
|
@ -663,24 +765,9 @@ Free a pool and temporary objects it refers to (callable from C)
|
||||||
Note: Don't use this when fullscreen is enabled -- the screen
|
Note: Don't use this when fullscreen is enabled -- the screen
|
||||||
sometimes includes, sometimes excludes the menu bar area. */
|
sometimes includes, sometimes excludes the menu bar area. */
|
||||||
{
|
{
|
||||||
CGFloat res;
|
struct EmacsMargins margins = ns_screen_margins(screen);
|
||||||
|
|
||||||
if (ns_menu_bar_should_be_hidden())
|
CGFloat res = margins.top;
|
||||||
{
|
|
||||||
res = 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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res);
|
NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res);
|
||||||
|
|
||||||
|
@ -7867,9 +7954,10 @@ - (void)zoom:(id)sender
|
||||||
// the menu-bar.
|
// the menu-bar.
|
||||||
[super zoom:sender];
|
[super zoom:sender];
|
||||||
|
|
||||||
#elsif 0
|
#elif 0
|
||||||
// Native zoom done using the standard zoom animation, plus an
|
// 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];
|
[super zoom:sender];
|
||||||
|
|
||||||
// After the native zoom, resize the resulting frame to fill the
|
// After the native zoom, resize the resulting frame to fill the
|
||||||
|
@ -7889,6 +7977,9 @@ - (void)zoom:(id)sender
|
||||||
NSTRACE_FSTYPE ("fullscreenState", fs_state);
|
NSTRACE_FSTYPE ("fullscreenState", fs_state);
|
||||||
|
|
||||||
NSRect sr = [screen frame];
|
NSRect sr = [screen frame];
|
||||||
|
struct EmacsMargins margins
|
||||||
|
= ns_screen_margins_ignoring_hidden_dock(screen);
|
||||||
|
|
||||||
NSRect wr = [self frame];
|
NSRect wr = [self frame];
|
||||||
NSTRACE_RECT ("Rect after zoom", wr);
|
NSTRACE_RECT ("Rect after zoom", wr);
|
||||||
|
|
||||||
|
@ -7897,15 +7988,15 @@ - (void)zoom:(id)sender
|
||||||
if (fs_state == FULLSCREEN_MAXIMIZED
|
if (fs_state == FULLSCREEN_MAXIMIZED
|
||||||
|| fs_state == FULLSCREEN_HEIGHT)
|
|| fs_state == FULLSCREEN_HEIGHT)
|
||||||
{
|
{
|
||||||
newWr.origin.x = 0;
|
newWr.origin.y = sr.origin.y + margins.bottom;
|
||||||
newWr.size.height = sr.size.height - ns_menu_bar_height(screen);
|
newWr.size.height = sr.size.height - margins.top - margins.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_state == FULLSCREEN_MAXIMIZED
|
if (fs_state == FULLSCREEN_MAXIMIZED
|
||||||
|| fs_state == FULLSCREEN_WIDTH)
|
|| fs_state == FULLSCREEN_WIDTH)
|
||||||
{
|
{
|
||||||
newWr.origin.y = 0;
|
newWr.origin.x = sr.origin.x + margins.left;
|
||||||
newWr.size.width = sr.size.width;
|
newWr.size.width = sr.size.width - margins.right - margins.left;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newWr.size.width != wr.size.width
|
if (newWr.size.width != wr.size.width
|
||||||
|
@ -7918,13 +8009,20 @@ - (void)zoom:(id)sender
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Non-native zoom which is done instantaneously. The resulting frame
|
// Non-native zoom which is done instantaneously. The resulting
|
||||||
// covers the entire screen, except the menu-bar, if present.
|
// frame covers the entire screen, except the menu-bar and dock, if
|
||||||
|
// present.
|
||||||
NSScreen * screen = [self screen];
|
NSScreen * screen = [self screen];
|
||||||
if (screen != nil)
|
if (screen != nil)
|
||||||
{
|
{
|
||||||
NSRect sr = [screen frame];
|
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
|
sr = [[self delegate] windowWillUseStandardFrame:self
|
||||||
defaultFrame:sr];
|
defaultFrame:sr];
|
||||||
|
|
Loading…
Add table
Reference in a new issue