Create a gist now

Instantly share code, notes, and snippets.

Add ns-toggle-fullscreen to Emacs 24
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 157b2dd..f3807b7 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -1263,6 +1263,11 @@ the operating system.")
(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)
;; arch-tag: eb138a45-4e2e-4d68-b1c9-a39665731644
diff --git a/src/nsfns.m b/src/nsfns.m
index 642ff79..03ffcf7 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2589,6 +2589,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;
+}
+
/* ==========================================================================
@@ -2676,6 +2704,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 29d312a..17b19e4 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -95,8 +95,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 9256c08..8bbb575 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -686,6 +686,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];
@@ -1131,8 +1138,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)
@@ -1197,7 +1210,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);
@@ -5609,6 +5622,59 @@ extern void update_window_cursor (struct window *w, int on);
@implementation EmacsWindow
+-(NSWindow *)toggleFullscreen {
+ 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
{
@@ -5667,6 +5733,32 @@ extern void update_window_cursor (struct window *w, int on);
@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 */
+
/* ==========================================================================
@markhellewell

Thankyou for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment