summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/NEWS2
-rw-r--r--src/ChangeLog27
-rw-r--r--src/nsfns.m2
-rw-r--r--src/nsterm.h18
-rw-r--r--src/nsterm.m296
6 files changed, 333 insertions, 16 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 6f2b178fcd7..2c1e3758ea0 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
+2012-09-30 Jan Djärv <jan.h.d@swipnet.se>
+
+ * NEWS: The NS port supports fullscreen.
+
2012-09-17 Glenn Morris <rgm@gnu.org>
* refcards/emacsver.tex: New file.
diff --git a/etc/NEWS b/etc/NEWS
index 0aff5e40251..e6f09d83f43 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -187,6 +187,8 @@ The PCL-CVS commands are still available via the keyboard.
---
*** New input method `vietnamese-vni'.
+** The NS port supports fullscreen.
+
* Editing Changes in Emacs 24.3
diff --git a/src/ChangeLog b/src/ChangeLog
index 1f240b219e0..6aaa6bc88f8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,30 @@
+2012-09-30 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfns.m (ns_frame_parm_handlers): Add x_set_fullscreen.
+
+ * nsterm.m (NEW_STYLE_FS): New define.
+ (ns_fullscreen_hook, windowWillEnterFullScreen)
+ (windowDidEnterFullScreen, windowWillExitFullScreen)
+ (windowDidExitFullScreen, toggleFullScreen, handleFS)
+ (setFSValue): New functions.
+ (EmacsFSWindow): New implementation.
+ (canBecomeKeyWindow): New function for EmacsFSWindow.
+ (ns_create_terminal): Set fullscreen_hook to ns_fullscreen_hook.
+ (dealloc): Release nonfs_window if in fullscreen.
+ (updateFrameSize:): Call windowDidMove to update top/left.
+ (windowWillResize:toSize:): Check if frame is still maximized.
+ (initFrameFromEmacs:): Initialize fs_state, fs_before_fs,
+ next_maximized, maximized_width, maximized_height and nonfs_window.
+ Call setCollectionBehavior if NEW_STYLE_FS. Initialize bwidth and
+ tbar_height.
+ (windowWillUseStandardFrame:defaultFrame:): Update frame parameter
+ fullscreen. Set maximized_width/height. Act on next_maximized.
+
+ * nsterm.h (MAC_OS_X_VERSION_10_7, MAC_OS_X_VERSION_10_8): New.
+ (EmacsView): Add variables for fullscreen.
+ (handleFS, setFSValue, toggleFullScreen): New in EmacsView.
+ (EmacsFSWindow): New interface for fullscreen.
+
2012-09-30 Juanma Barranquero <lekktu@gmail.com>
* makefile.w32-in ($(BLD)/profiler.$(O)): Update dependencies.
diff --git a/src/nsfns.m b/src/nsfns.m
index 94ace360438..c96ec99ed2e 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1018,7 +1018,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
x_set_fringe_width, /* generic OK */
x_set_fringe_width, /* generic OK */
0, /* x_set_wait_for_wm, will ignore */
- 0, /* x_set_fullscreen will ignore */
+ x_set_fullscreen, /* generic OK */
x_set_font_backend, /* generic OK */
x_set_alpha,
0, /* x_set_sticky */
diff --git a/src/nsterm.h b/src/nsterm.h
index 97fc6be20e5..f06e0cb0f7f 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -38,6 +38,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef MAC_OS_X_VERSION_10_6
#define MAC_OS_X_VERSION_10_6 1060
#endif
+#ifndef MAC_OS_X_VERSION_10_7
+#define MAC_OS_X_VERSION_10_7 1070
+#endif
+#ifndef MAC_OS_X_VERSION_10_8
+#define MAC_OS_X_VERSION_10_8 1080
+#endif
#endif /* NS_IMPL_COCOA */
#ifdef __OBJC__
@@ -80,6 +86,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
BOOL windowClosing;
NSString *workingText;
BOOL processingCompose;
+ int fs_state, fs_before_fs, next_maximized, tbar_height, bwidth;
+ int maximized_width, maximized_height;
+ NSWindow *nonfs_window;
@public
struct frame *emacsframe;
int rows, cols;
@@ -104,6 +113,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
- (EmacsToolbar *) toolbar;
- (void) deleteWorkingText;
- (void) updateFrameSize: (BOOL) delay;
+- (void) handleFS;
+- (void) setFSValue: (int)value;
+- (void) toggleFullScreen: (id) sender;
#ifdef NS_IMPL_GNUSTEP
/* Not declared, but useful. */
@@ -120,6 +132,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
@end
+/* Fullscreen version of the above. */
+@interface EmacsFSWindow : EmacsWindow
+{
+}
+@end
+
/* ==========================================================================
The main menu implementation
diff --git a/src/nsterm.m b/src/nsterm.m
index 5af3c2e2ae1..d41c38f4e40 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -72,6 +72,11 @@ int term_trace_num = 0;
#define NSTRACE(x)
#endif
+#if defined (NS_IMPL_COCOA) && \
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+#define NEW_STYLE_FS
+#endif
+
extern NSString *NSMenuDidBeginTrackingNotification;
/* ==========================================================================
@@ -1306,6 +1311,17 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
}
+static void
+ns_fullscreen_hook (FRAME_PTR f)
+{
+ EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
+
+ if (! f->async_visible) return;
+
+ block_input ();
+ [view handleFS];
+ unblock_input ();
+}
/* ==========================================================================
@@ -3932,7 +3948,7 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
terminal->frame_rehighlight_hook = ns_frame_rehighlight;
terminal->frame_raise_lower_hook = ns_frame_raise_lower;
- terminal->fullscreen_hook = 0; /* see XTfullscreen_hook */
+ terminal->fullscreen_hook = ns_fullscreen_hook;
terminal->set_vertical_scroll_bar_hook = ns_set_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = ns_condemn_scroll_bars;
@@ -4687,6 +4703,8 @@ not_in_argv (NSString *arg)
{
NSTRACE (EmacsView_dealloc);
[toolbar release];
+ if (fs_state == FULLSCREEN_BOTH)
+ [nonfs_window release];
[super dealloc];
}
@@ -5405,6 +5423,7 @@ not_in_argv (NSString *arg)
SET_FRAME_GARBAGED (emacsframe);
cancel_mouse_face (emacsframe);
[view setFrame: NSMakeRect (0, 0, neww, newh)];
+ [self windowDidMove:nil]; // Update top/left.
}
}
@@ -5414,6 +5433,19 @@ not_in_argv (NSString *arg)
NSTRACE (windowWillResize);
/*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */
+ if (fs_state == FULLSCREEN_MAXIMIZED
+ && (maximized_width != (int)frameSize.width
+ || maximized_height != (int)frameSize.height))
+ [self setFSValue: FULLSCREEN_NONE];
+ else if (fs_state == FULLSCREEN_WIDTH
+ && maximized_width != (int)frameSize.width)
+ [self setFSValue: FULLSCREEN_NONE];
+ else if (fs_state == FULLSCREEN_HEIGHT
+ && maximized_height != (int)frameSize.height)
+ [self setFSValue: FULLSCREEN_NONE];
+ if (fs_state == FULLSCREEN_NONE)
+ maximized_width = maximized_height = -1;
+
cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe,
#ifdef NS_IMPL_GNUSTEP
frameSize.width + 3);
@@ -5595,6 +5627,10 @@ not_in_argv (NSString *arg)
windowClosing = NO;
processingCompose = NO;
scrollbarsNeedingUpdate = 0;
+ fs_state = FULLSCREEN_NONE;
+ fs_before_fs = next_maximized = -1;
+ maximized_width = maximized_height = -1;
+ nonfs_window = nil;
/*fprintf (stderr,"init with %d, %d\n",f->text_cols, f->text_lines); */
@@ -5619,9 +5655,13 @@ not_in_argv (NSString *arg)
backing: NSBackingStoreBuffered
defer: YES];
+#ifdef NEW_STYLE_FS
+ [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+#endif
+
wr = [win frame];
- f->border_width = wr.size.width - r.size.width;
- FRAME_NS_TITLEBAR_HEIGHT (f) = wr.size.height - r.size.height;
+ bwidth = f->border_width = wr.size.width - r.size.width;
+ tbar_height = FRAME_NS_TITLEBAR_HEIGHT (f) = wr.size.height - r.size.height;
[win setAcceptsMouseMovedEvents: YES];
[win setDelegate: self];
@@ -5727,27 +5767,50 @@ not_in_argv (NSString *arg)
NSTRACE (windowWillUseStandardFrame);
- if (abs (defaultFrame.size.height - result.size.height)
- > FRAME_LINE_HEIGHT (emacsframe))
+ if (fs_before_fs != -1) /* Entering fullscreen */
+ {
+ result = defaultFrame;
+ }
+ else if (next_maximized == FULLSCREEN_HEIGHT
+ || (next_maximized == -1
+ && abs (defaultFrame.size.height - result.size.height)
+ > FRAME_LINE_HEIGHT (emacsframe)))
{
/* first click */
ns_userRect = result;
- result.size.height = defaultFrame.size.height;
+ maximized_height = result.size.height = defaultFrame.size.height;
+ maximized_width = -1;
result.origin.y = defaultFrame.origin.y;
+ [self setFSValue: FULLSCREEN_HEIGHT];
+ }
+ else if (next_maximized == FULLSCREEN_WIDTH)
+ {
+ ns_userRect = result;
+ maximized_width = result.size.width = defaultFrame.size.width;
+ maximized_height = -1;
+ result.origin.x = defaultFrame.origin.x;
+ [self setFSValue: FULLSCREEN_WIDTH];
+ }
+ else if (next_maximized == FULLSCREEN_MAXIMIZED
+ || (next_maximized == -1
+ && abs (defaultFrame.size.width - result.size.width)
+ > FRAME_COLUMN_WIDTH (emacsframe)))
+ {
+ result = defaultFrame; /* second click */
+ maximized_width = result.size.width;
+ maximized_height = result.size.height;
+ [self setFSValue: FULLSCREEN_MAXIMIZED];
}
else
{
- if (abs (defaultFrame.size.width - result.size.width)
- > FRAME_COLUMN_WIDTH (emacsframe))
- result = defaultFrame; /* second click */
- else
- {
- /* restore */
- result = ns_userRect.size.height ? ns_userRect : result;
- ns_userRect = NSMakeRect (0, 0, 0, 0);
- }
+ /* restore */
+ result = ns_userRect.size.height ? ns_userRect : result;
+ ns_userRect = NSMakeRect (0, 0, 0, 0);
+ [self setFSValue: FULLSCREEN_NONE];
+ maximized_width = maximized_width = -1;
}
+ if (fs_before_fs == -1) next_maximized = -1;
[self windowWillResize: sender toSize: result.size];
return result;
}
@@ -5799,6 +5862,200 @@ not_in_argv (NSString *arg)
}
}
+- (void)windowWillEnterFullScreen:(NSNotification *)notification
+{
+ fs_before_fs = fs_state;
+}
+
+- (void)windowDidEnterFullScreen:(NSNotification *)notification
+{
+ [self setFSValue: FULLSCREEN_BOTH];
+#ifndef NEW_STYLE_FS
+ fprintf(stderr, "%s %d\n", __func__, FRAME_PIXEL_WIDTH (emacsframe));
+ [self windowDidBecomeKey:notification];
+#endif
+}
+
+- (void)windowWillExitFullScreen:(NSNotification *)notification
+{
+ if (next_maximized != -1)
+ fs_before_fs = next_maximized;
+}
+
+- (void)windowDidExitFullScreen:(NSNotification *)notification
+{
+ [self setFSValue: fs_before_fs];
+ fs_before_fs = -1;
+ if (next_maximized != -1)
+ [[self window] performZoom:self];
+}
+
+- (void)toggleFullScreen: (id)sender
+{
+ /* Bugs remain:
+ 1) Having fullscreen in initial/default frame alist.
+ 2) Fullscreen in default frame alist only applied to first frame.
+ */
+
+#ifdef NEW_STYLE_FS
+ [[self window] toggleFullScreen:sender];
+#else
+ NSWindow *w = [self window], *fw;
+ BOOL onFirstScreen = [[w screen]
+ isEqual:[[NSScreen screens] objectAtIndex:0]];
+ struct frame *f = emacsframe;
+ NSSize sz;
+ NSRect r;
+ NSColor *col = ns_lookup_indexed_color (NS_FACE_BACKGROUND
+ (FRAME_DEFAULT_FACE (f)),
+ f);
+
+ sz.width = FRAME_COLUMN_WIDTH (f);
+ sz.height = FRAME_LINE_HEIGHT (f);
+
+ if (fs_state != FULLSCREEN_BOTH)
+ {
+ /* Hide dock and menubar if we are on the primary screen. */
+ if (onFirstScreen)
+ {
+#if defined (NS_IMPL_COCOA) && \
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ NSApplicationPresentationOptions options
+ = NSApplicationPresentationAutoHideDock
+ | NSApplicationPresentationAutoHideMenuBar;
+
+ [NSApp setPresentationOptions: options];
+#else
+ [NSMenu setMenuBarVisible:NO];
+#endif
+ }
+
+ fw = [[EmacsFSWindow alloc]
+ initWithContentRect:[w contentRectForFrameRect:[w frame]]
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:YES
+ screen:[w screen]];
+
+ [fw setContentView:[w contentView]];
+ [fw setTitle:[w title]];
+ [fw makeKeyAndOrderFront:NSApp];
+ [fw setDelegate:self];
+ [fw makeFirstResponder:self];
+ [fw setAcceptsMouseMovedEvents: YES];
+ [fw useOptimizedDrawing: YES];
+ [fw setResizeIncrements: sz];
+ [fw setBackgroundColor: col];
+ if ([col alphaComponent] != 1.0)
+ [fw setOpaque: NO];
+
+ f->border_width = 0;
+ FRAME_NS_TITLEBAR_HEIGHT (f) = 0;
+
+ nonfs_window = w;
+ [self windowWillEnterFullScreen:nil];
+ [w orderOut:self];
+ r = [fw frameRectForContentRect:[[fw screen] frame]];
+ [fw setFrame: r display:YES animate:YES];
+ [self windowDidEnterFullScreen:nil];
+ }
+ else
+ {
+ fw = w;
+ w = nonfs_window;
+
+ if (onFirstScreen)
+ {
+#if defined (NS_IMPL_COCOA) && \
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ [NSApp setPresentationOptions: NSApplicationPresentationDefault];
+#else
+ [NSMenu setMenuBarVisible:YES];
+#endif
+ }
+
+ [w setContentView:[fw contentView]];
+ [w setResizeIncrements: sz];
+ [w setBackgroundColor: col];
+ if ([col alphaComponent] != 1.0)
+ [w setOpaque: NO];
+
+ f->border_width = bwidth;
+ FRAME_NS_TITLEBAR_HEIGHT (f) = tbar_height;
+
+ [self windowWillExitFullScreen:nil];
+ [fw setFrame: [w frame] display:YES animate:YES];
+ [fw close];
+ [w makeKeyAndOrderFront:NSApp];
+ [self windowDidExitFullScreen:nil];
+ }
+#endif
+}
+
+- (void)handleFS
+{
+ if (fs_state != emacsframe->want_fullscreen)
+ {
+ if (fs_state == FULLSCREEN_BOTH)
+ {
+ [self toggleFullScreen:self];
+ }
+
+ switch (emacsframe->want_fullscreen)
+ {
+ case FULLSCREEN_BOTH:
+ [self toggleFullScreen:self];
+ break;
+ case FULLSCREEN_WIDTH:
+ next_maximized = FULLSCREEN_WIDTH;
+ if (fs_state != FULLSCREEN_BOTH)
+ [[self window] performZoom:self];
+ break;
+ case FULLSCREEN_HEIGHT:
+ next_maximized = FULLSCREEN_HEIGHT;
+ if (fs_state != FULLSCREEN_BOTH)
+ [[self window] performZoom:self];
+ break;
+ case FULLSCREEN_MAXIMIZED:
+ next_maximized = FULLSCREEN_MAXIMIZED;
+ if (fs_state != FULLSCREEN_BOTH)
+ [[self window] performZoom:self];
+ break;
+ case FULLSCREEN_NONE:
+ if (fs_state != FULLSCREEN_BOTH)
+ {
+ next_maximized = FULLSCREEN_NONE;
+ [[self window] performZoom:self];
+ }
+ break;
+ }
+
+ emacsframe->want_fullscreen = FULLSCREEN_NONE;
+ }
+
+}
+
+- (void) setFSValue: (int)value
+{
+ Lisp_Object lval = Qnil;
+ switch (value)
+ {
+ case FULLSCREEN_BOTH:
+ lval = Qfullboth;
+ break;
+ case FULLSCREEN_WIDTH:
+ lval = Qfullwidth;
+ break;
+ case FULLSCREEN_HEIGHT:
+ lval = Qfullheight;
+ break;
+ case FULLSCREEN_MAXIMIZED:
+ lval = Qmaximized;
+ break;
+ }
+ store_frame_param (emacsframe, Qfullscreen, lval);
+ fs_state = value;
+}
- (void)mouseEntered: (NSEvent *)theEvent
{
@@ -6290,6 +6547,15 @@ not_in_argv (NSString *arg)
@end /* EmacsWindow */
+@implementation EmacsFSWindow
+
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+@end
+
/* ==========================================================================
EmacsScroller implementation