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

Add support for fullscreen in the NS port.

* etc/NEWS: The NS port supports fullscreen.

* src/nsfns.m (ns_frame_parm_handlers): Add x_set_fullscreen.

* src/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.

* src/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.
parent ee41332b
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.
......
......@@ -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
......
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.
......
......@@ -1018,7 +1018,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side
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 */
......
......@@ -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
......
......@@ -72,6 +72,11 @@ Updated by Christian Limpach (chris@nice.ch)
#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 @@ Free a pool and temporary objects it refers to (callable from C)
}
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 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
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 @@ - (void)dealloc
{
NSTRACE (EmacsView_dealloc);
[toolbar release];
if (fs_state == FULLSCREEN_BOTH)
[nonfs_window release];
[super dealloc];
}
......@@ -5405,6 +5423,7 @@ - (void) updateFrameSize: (BOOL) delay;
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 @@ - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
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 @@ - (BOOL)isOpaque
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 @@ - (BOOL)isOpaque
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 @@ - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
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 @@ - (void)windowDidMiniaturize: sender
}
}
- (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 @@ - (void)mouseDragged: (NSEvent *)theEvent
@end /* EmacsWindow */
@implementation EmacsFSWindow
- (BOOL)canBecomeKeyWindow
{
return YES;
}
@end
/* ==========================================================================
EmacsScroller implementation
......
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