mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-28 07:45:00 +00:00
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
156
src/nsterm.m
156
src/nsterm.m
@ -646,41 +646,128 @@ Free a pool and temporary objects it refers to (callable from C)
|
||||
}
|
||||
|
||||
|
||||
/* 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:)];
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
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. */
|
||||
sometimes includes, sometimes excludes the menu bar area. */
|
||||
{
|
||||
CGFloat res;
|
||||
struct EmacsMargins margins = ns_screen_margins(screen);
|
||||
|
||||
if (ns_menu_bar_should_be_hidden())
|
||||
{
|
||||
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;
|
||||
|
||||
}
|
||||
CGFloat res = margins.top;
|
||||
|
||||
NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res);
|
||||
|
||||
@ -7867,9 +7954,10 @@ - (void)zoom:(id)sender
|
||||
// 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 @@ - (void)zoom:(id)sender
|
||||
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 @@ - (void)zoom:(id)sender
|
||||
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 @@ - (void)zoom:(id)sender
|
||||
}
|
||||
}
|
||||
#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];
|
||||
|
Loading…
Reference in New Issue
Block a user