Commit f0a1382a authored by Jan Djärv's avatar Jan Djärv

Introduce ns-auto-hide-menu-bar to hide menubar for Emacs frames.

Code by Anders Lindgren.

* nsterm.m (ns_menu_bar_is_hidden): New variable.
(ns_constrain_all_frames, ns_menu_bar_should_be_hidden)
(ns_update_auto_hide_menu_bar): New functions.
(ns_update_begin): Call ns_update_auto_hide_menu_bar.
(applicationDidBecomeActive): Call ns_update_auto_hide_menu_bar and
ns_constrain_all_frames.
(constrainFrameRect): Return at once if ns_menu_bar_should_be_hidden.
(syms_of_nsterm): DEFVAR ns-auto-hide-menu-bar, init to Qnil.
parent 5c380ffb
2011-03-27 Anders Lindgren <andlind@gmail.com>
* nsterm.m (ns_menu_bar_is_hidden): New variable.
(ns_constrain_all_frames, ns_menu_bar_should_be_hidden)
(ns_update_auto_hide_menu_bar): New functions.
(ns_update_begin): Call ns_update_auto_hide_menu_bar.
(applicationDidBecomeActive): Call ns_update_auto_hide_menu_bar and
ns_constrain_all_frames.
(constrainFrameRect): Return at once if ns_menu_bar_should_be_hidden.
(syms_of_nsterm): DEFVAR ns-auto-hide-menu-bar, init to Qnil.
2011-03-27 Jan Djärv <jan.h.d@swipnet.se>
* nsmenu.m (runDialogAt): Remove argument to timer_check.
......@@ -170,6 +170,7 @@ Updated by Christian Limpach (chris@nice.ch)
static BOOL ns_fake_keydown = NO;
int ns_tmp_flags; /* FIXME */
struct nsfont_info *ns_tmp_font; /* FIXME */
static BOOL ns_menu_bar_is_hidden = NO;
/*static int debug_lock = 0; */
/* event loop */
......@@ -505,6 +506,118 @@ Free a pool and temporary objects it refers to (callable from C)
}
//
// Window constraining
// -------------------
//
// To ensure that the windows are not placed under the menu bar, they
// are typically moved by the call-back constrainFrameRect. However,
// by overriding it, it's possible to inhibit this, leaving the window
// in it's original position.
//
// It's possible to hide the menu bar. However, technically, it's only
// possible to hide it when the application is active. To ensure that
// this work properly, the menu bar and window constraining are
// deferred until the application becomes active.
//
// Even though it's not possible to manually move a window above the
// top of the screen, it is allowed if it's done programmatically,
// when the menu is hidden. This allows the editable area to cover the
// full screen height.
//
// Test cases
// ----------
//
// Use the following extra files:
//
// init.el:
// ;; Hide menu and place frame slightly above the top of the screen.
// (setq ns-auto-hide-menu-bar t)
// (set-frame-position (selected-frame) 0 -20)
//
// Test 1:
//
// emacs -Q -l init.el
//
// Result: No menu bar, and the title bar should be above the screen.
//
// Test 2:
//
// emacs -Q
//
// Result: Menu bar visible, frame placed immediately below the menu.
//
static void
ns_constrain_all_frames (void)
{
Lisp_Object tail, frame;
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
if (FRAME_NS_P (f))
{
NSView *view = FRAME_NS_VIEW (f);
/* This no-op will trigger the default window placing
* constriant system. */
f->output_data.ns->dont_constrain = 0;
[[view window] setFrameOrigin:[[view window] frame].origin];
}
}
}
/* True, if the menu bar should be hidden. */
static BOOL
ns_menu_bar_should_be_hidden (void)
{
return !NILP (ns_auto_hide_menu_bar)
&& [NSApp respondsToSelector:@selector(setPresentationOptions:)];
}
/* Show or hide the menu bar, based on user setting. */
static void
ns_update_auto_hide_menu_bar (void)
{
BLOCK_INPUT;
NSTRACE (ns_update_auto_hide_menu_bar);
if (NSApp != nil
&& [NSApp isActive]
&& [NSApp respondsToSelector:@selector(setPresentationOptions:)])
{
// Note, "setPresentationOptions" triggers an error unless the
// application is active.
BOOL menu_bar_should_be_hidden = ns_menu_bar_should_be_hidden ();
if (menu_bar_should_be_hidden != ns_menu_bar_is_hidden)
{
NSApplicationPresentationOptions options
= NSApplicationPresentationAutoHideDock;
if (menu_bar_should_be_hidden)
options |= NSApplicationPresentationAutoHideMenuBar;
[NSApp setPresentationOptions: options];
ns_menu_bar_is_hidden = menu_bar_should_be_hidden;
if (!ns_menu_bar_is_hidden)
{
ns_constrain_all_frames ();
}
}
}
UNBLOCK_INPUT;
}
static void
ns_update_begin (struct frame *f)
/* --------------------------------------------------------------------------
......@@ -515,6 +628,8 @@ Free a pool and temporary objects it refers to (callable from C)
NSView *view = FRAME_NS_VIEW (f);
NSTRACE (ns_update_begin);
ns_update_auto_hide_menu_bar ();
ns_updating_frame = f;
[view lockFocus];
......@@ -4205,7 +4320,13 @@ - (void)applicationWillBecomeActive: (NSNotification *)notification
}
- (void)applicationDidBecomeActive: (NSNotification *)notification
{
NSTRACE (applicationDidBecomeActive);
//ns_app_active=YES;
ns_update_auto_hide_menu_bar ();
// No constrining takes place when the application is not active.
ns_constrain_all_frames ();
}
- (void)applicationDidResignActive: (NSNotification *)notification
{
......@@ -5689,7 +5810,10 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
/* When making the frame visible for the first time, we want to
constrain. Other times not. */
struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
if (f->output_data.ns->dont_constrain)
NSTRACE (constrainFrameRect);
if (f->output_data.ns->dont_constrain
|| ns_menu_bar_should_be_hidden ())
return frameRect;
f->output_data.ns->dont_constrain = 1;
......@@ -6361,6 +6485,10 @@ Convert an X font name (XLFD) to an NS font name.
staticpro (&last_mouse_motion_frame);
last_mouse_motion_frame = Qnil;
DEFVAR_LISP ("ns-auto-hide-menu-bar", ns_auto_hide_menu_bar,
"Non-nil means that the menu bar is hidden, but appears when the mouse is near. Only works on OSX 10.6 or later.");
ns_auto_hide_menu_bar = Qnil;
/* TODO: move to common code */
DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
doc: /* If not nil, Emacs uses toolkit scroll bars. */);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment