summaryrefslogtreecommitdiff
path: root/src/nsterm.m
diff options
context:
space:
mode:
authorJan Djärv <jan.h.d@swipnet.se>2011-03-27 12:36:44 +0200
committerJan Djärv <jan.h.d@swipnet.se>2011-03-27 12:36:44 +0200
commitf0a1382af3afa31708d3ce2f4c28bce61565aada (patch)
tree3496ce73efe0ae5a747377d5154265f10b64bed9 /src/nsterm.m
parent5c380ffb17f2fb6f22d9f24a7732b7e4a1e0cd52 (diff)
downloademacs-f0a1382af3afa31708d3ce2f4c28bce61565aada.tar.gz
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.
Diffstat (limited to 'src/nsterm.m')
-rw-r--r--src/nsterm.m130
1 files changed, 129 insertions, 1 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index c7cd411c614..ebfa875ae0e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -170,6 +170,7 @@ BOOL ns_in_resize = NO;
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 @@ ns_resize_handle_rect (NSWindow *window)
}
+//
+// 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 @@ ns_update_begin (struct frame *f)
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 @@ ns_term_shutdown (int sig)
}
- (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 @@ ns_term_shutdown (int sig)
/* 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 @@ allowing it to be used at a lower level for accented character entry.");
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. */);