Created
July 20, 2011 22:19
-
-
Save mstepniowski/1096074 to your computer and use it in GitHub Desktop.
Add Lion-based fullscreen mode to Emacs 24
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el | |
index 447d7fd..27bba4a 100644 | |
--- a/lisp/term/ns-win.el | |
+++ b/lisp/term/ns-win.el | |
@@ -929,6 +929,11 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") | |
(add-to-list 'window-system-initialization-alist '(ns . ns-initialize-window-system)) | |
+(declare-function ns-toggle-fullscreen-internal "nsfns.m" ()) | |
+(defun ns-toggle-fullscreen () | |
+ (interactive) | |
+ (ns-toggle-fullscreen-internal)) | |
+ | |
(provide 'ns-win) | |
;;; ns-win.el ends here | |
diff --git a/src/nsfns.m b/src/nsfns.m | |
index 0452086..61d4d65 100644 | |
--- a/src/nsfns.m | |
+++ b/src/nsfns.m | |
@@ -2573,6 +2573,34 @@ Value is t if tooltip was open, nil otherwise. */) | |
#endif | |
+DEFUN ("ns-toggle-fullscreen-internal", Fns_toggle_fullscreen_internal, Sns_toggle_fullscreen_internal, | |
+ 0, 0, 0, | |
+ doc: /* Toggle fulscreen mode */) | |
+ () | |
+{ | |
+ struct frame *f = SELECTED_FRAME(); | |
+ EmacsWindow *window = ns_get_window(f); | |
+ | |
+ EmacsWindow *new_window = [window toggleFullscreen]; | |
+ FRAME_NS_WINDOW(f) = new_window; | |
+ | |
+ NSRect r = [new_window contentRectForFrameRect:[new_window frame]]; | |
+ int cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, r.size.width); | |
+ int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, r.size.height); | |
+ | |
+ change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */ | |
+ FRAME_PIXEL_WIDTH (f) = (int)r.size.width; | |
+ FRAME_PIXEL_HEIGHT (f) = (int)r.size.height; | |
+ | |
+ f->border_width = [new_window frame].size.width - r.size.width; | |
+ FRAME_NS_TITLEBAR_HEIGHT (f) = | |
+ [new_window frame].size.height - r.size.height; | |
+ | |
+ [[new_window delegate] windowDidMove:nil]; | |
+ | |
+ return Qnil; | |
+} | |
+ | |
/* ========================================================================== | |
@@ -2658,6 +2686,8 @@ be used as the image of the icon representing the frame. */); | |
defsubr (&Sx_show_tip); | |
defsubr (&Sx_hide_tip); | |
+ defsubr (&Sns_toggle_fullscreen_internal); | |
+ | |
/* used only in fontset.c */ | |
check_window_system_func = check_ns; | |
diff --git a/src/nsterm.h b/src/nsterm.h | |
index f419391..cc3b829 100644 | |
--- a/src/nsterm.h | |
+++ b/src/nsterm.h | |
@@ -116,8 +116,25 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |
{ | |
NSPoint grabOffset; | |
} | |
+ | |
+-(EmacsWindow *)toggleFullscreen; | |
+ | |
+@end | |
+ | |
+/* 10.5 or below is not supported [NSWindow setStyleMask:], so require content swap hack */ | |
+@interface EmacsFullWindow : EmacsWindow { | |
+ EmacsWindow *normalWindow; | |
+} | |
+ | |
+-(id)initWithNormalWindow:(EmacsWindow *)window; | |
+-(EmacsWindow *)getNormalWindow; | |
+ | |
@end | |
+// dummy for 10.5- | |
+#define NSApplicationPresentationDefault 0 | |
+#define NSApplicationPresentationAutoHideDock (1 << 0) | |
+#define NSApplicationPresentationAutoHideMenuBar (1 << 2) | |
/* ========================================================================== | |
diff --git a/src/nsterm.m b/src/nsterm.m | |
index 546247a..b59fa06 100644 | |
--- a/src/nsterm.m | |
+++ b/src/nsterm.m | |
@@ -797,6 +797,13 @@ ns_focus (struct frame *f, NSRect *r, int n) | |
/*debug_lock--; */ | |
} | |
+ if (view) { | |
+ EmacsFullWindow *win = [view window]; | |
+ if ([win isKindOfClass:[EmacsFullWindow class]]) { | |
+ [[win getNormalWindow] orderOut:nil]; | |
+ } | |
+ } | |
+ | |
if (view) | |
#ifdef NS_IMPL_GNUSTEP | |
r ? [view lockFocusInRect: u] : [view lockFocus]; | |
@@ -1262,8 +1269,14 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) | |
f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f); | |
compute_fringe_widths (f, 0); | |
- pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); | |
- pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); | |
+ if ([window isKindOfClass:[EmacsFullWindow class]]) { | |
+ pixelwidth = [[window screen] frame].size.width; | |
+ pixelheight = [[window screen] frame].size.height; | |
+ } | |
+ else { | |
+ pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); | |
+ pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); | |
+ } | |
/* If we have a toolbar, take its height into account. */ | |
if (tb) | |
@@ -1312,7 +1325,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) | |
change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */ | |
FRAME_PIXEL_WIDTH (f) = pixelwidth; | |
FRAME_PIXEL_HEIGHT (f) = pixelheight; | |
-/* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */ | |
+ /* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */ | |
mark_window_cursors_off (XWINDOW (f->root_window)); | |
cancel_mouse_face (f); | |
@@ -5861,6 +5874,65 @@ ns_term_shutdown (int sig) | |
} | |
+-(NSWindow *)toggleFullscreen { | |
+ // OS X Lion | |
+ if ([super respondsToSelector: @selector(toggleFullScreen:)]) { | |
+ [super toggleFullScreen:self]; | |
+ return self; | |
+ } | |
+ | |
+ BOOL isFullscreen = [[self className] isEqualToString:@"EmacsFullWindow"]; | |
+ NSWindow *win; | |
+ | |
+ if (isFullscreen) { | |
+ EmacsFullWindow *f = (EmacsFullWindow *)self; | |
+ EmacsWindow *w = [f getNormalWindow]; | |
+ | |
+ [w setContentView:[f contentView]]; | |
+ [w makeKeyAndOrderFront:nil]; | |
+ | |
+ [f close]; | |
+ | |
+ win = w; | |
+ | |
+ if ([[self screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) { | |
+ if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) { | |
+ [NSApp setPresentationOptions:NSApplicationPresentationDefault]; | |
+ } | |
+ else { | |
+ [NSMenu setMenuBarVisible:YES]; | |
+ } | |
+ } | |
+ } | |
+ else { | |
+ [self deminiaturize:nil]; | |
+ | |
+ if ([[self screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) { | |
+ if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) { | |
+ [NSApp setPresentationOptions:NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar]; | |
+ } | |
+ else { | |
+ [NSMenu setMenuBarVisible:NO]; | |
+ } | |
+ } | |
+ | |
+ [self orderOut:nil]; | |
+ | |
+ EmacsFullWindow *f = [[EmacsFullWindow alloc] initWithNormalWindow:self]; | |
+ EmacsView *view = (EmacsView *)[self delegate]; | |
+ [f setDelegate:view]; | |
+ [f makeFirstResponder:view]; | |
+ [f setContentView:[self contentView]]; | |
+ [f setContentSize:[[self screen] frame].size]; | |
+ [f setTitle:[self title]]; | |
+ [f makeKeyAndOrderFront:nil]; | |
+ | |
+ win = f; | |
+ } | |
+ | |
+ return win; | |
+} | |
+ | |
/* called only on resize clicks by special case in EmacsApp-sendEvent */ | |
- (void)mouseDown: (NSEvent *)theEvent | |
{ | |
@@ -5916,6 +5988,32 @@ ns_term_shutdown (int sig) | |
@end /* EmacsWindow */ | |
+@implementation EmacsFullWindow | |
+ | |
+-(BOOL)canBecomeKeyWindow { | |
+ return YES; | |
+} | |
+ | |
+-(id)initWithNormalWindow:(EmacsWindow *)window { | |
+ self = [super initWithContentRect:[window contentRectForFrameRect:[[window screen] frame]] | |
+ styleMask:NSBorderlessWindowMask | |
+ backing:NSBackingStoreBuffered | |
+ defer:YES]; | |
+ if (self) { | |
+ normalWindow = window; | |
+ [self setAcceptsMouseMovedEvents: YES]; | |
+ [self useOptimizedDrawing: YES]; | |
+ } | |
+ | |
+ return self; | |
+} | |
+ | |
+-(EmacsWindow *)getNormalWindow { | |
+ return normalWindow; | |
+} | |
+ | |
+@end /* EmacsFullWindow */ | |
+ | |
/* ========================================================================== | |
It partially works (tested with an Emacs version from homebrew) but unfortunately there are still some bugs. I will work on the patch during the weekend.
this doesn't work at all with a version built from bzr, there are no errors, it just does nothing
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Found this via Google! Does this work? :) What is the status of this patch?