木曜日, 6月 03, 2010

Cocoa Emacs 23.2.50 フルスクリーン

勉強がてらEmacsフルスクリーンパッチを書いてみました。既に他の方がやっておられるので二番煎じにはなりますが、若干手法が違います。また、Snow Leopardから導入されたAPIを利用しているのでSnow Leopard以降でしか動きません。あまりテストはしていないので自己責任でお使いください。


=== modified file 'lisp/term/ns-win.el'
--- lisp/term/ns-win.el 2010-04-16 06:58:56 +0000
+++ lisp/term/ns-win.el 2010-06-03 09:11:14 +0000
@@ -894,6 +894,13 @@

(declare-function ns-emacs-info-panel "nsfns.m" ())

+(defun ns-fullscreen-toggle ()
+ (interactive)
+ (ns-fullscreen-toggle-cocoa))
+
+(declare-function ns-fullscreen-toggle "nsfns.m" ())
+
+
(defun ns-do-emacs-info-panel ()
(interactive)
(ns-emacs-info-panel))

=== modified file 'src/nsfns.m'
--- src/nsfns.m 2010-04-16 06:58:56 +0000
+++ src/nsfns.m 2010-06-03 09:08:00 +0000
@@ -2096,6 +2096,24 @@
else
error ("%s", SDATA (result));
}
+
+DEFUN ("ns-fullscreen-toggle-cocoa",Fns_fullscreen_toggle_cocoa,Sns_fullscreen_toggle_cocoa, 0, 0, 0,
+ doc: /* Toggle cooca full-screen */)
+ ()
+{
+ struct frame *sf = SELECTED_FRAME ();
+ check_ns();
+ if(sf)
+ {
+ BLOCK_INPUT;
+ EmacsView *view = (EmacsView*)FRAME_NS_VIEW(sf);
+ EmacsWindow *window = (EmacsWindow*)[view window];
+ [window setFullScreen:![window isFullScreen]];
+ UNBLOCK_INPUT;
+ }
+ return 0;
+}
+
#endif


@@ -2672,6 +2690,7 @@
defsubr (&Sns_list_colors);
#ifdef NS_IMPL_COCOA
defsubr (&Sns_do_applescript);
+ defsubr (&Sns_fullscreen_toggle_cocoa);
#endif
defsubr (&Sxw_color_defined_p);
defsubr (&Sxw_color_values);

=== modified file 'src/nsterm.h'
--- src/nsterm.h 2010-04-16 06:58:56 +0000
+++ src/nsterm.h 2010-06-03 09:26:01 +0000
@@ -94,7 +94,13 @@
@interface EmacsWindow : NSWindow
{
NSPoint grabOffset;
+ BOOL fullScreen;
+ NSRect windowSize;
}
+
+- (void) setFullScreen: (BOOL)fullscreen;
+- (BOOL) isFullScreen;
+
@end



=== modified file 'src/nsterm.m'
--- src/nsterm.m 2010-05-28 02:22:49 +0000
+++ src/nsterm.m 2010-06-03 09:40:02 +0000
@@ -1151,7 +1151,17 @@
/* constrain to screen if we can */
if (screen)
{
- NSSize sz = [screen visibleFrame].size;
+ NSSize sz = NSMakeSize(0,0);
+ if([[window className] compare:@"EmacsWindow"] == NSOrderedSame){
+ EmacsWindow *ew = (EmacsWindow *)window;
+ if([ew isFullScreen]){
+ sz = [screen frame].size;
+ sz.height += 22;
+ }
+ }
+ if(sz.width == 0 && sz.height == 0){
+ sz = [screen visibleFrame].size;
+ }
NSSize ez = { wr.size.width - sz.width, wr.size.height - sz.height };
if (ez.width > 0)
{
@@ -5689,6 +5699,47 @@
[super mouseDragged: theEvent];
}

+-(NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)aScreen
+{
+ if ([self isFullScreen]) {
+ NSRect result = [[NSScreen mainScreen] frame];
+ result.size.height+= 22;
+ [[self delegate] windowWillResize:self toSize:result.size]; /* ad-hock implemention */
+ return result;
+ } else {
+ [[self delegate] windowWillResize:self toSize:frameRect.size]; /* ad-hock implemention */
+ return [super constrainFrameRect:frameRect toScreen:aScreen];
+ }
+}
+
+- (void) setFullScreen: (BOOL)newfullscreen
+{
+ fullScreen = newfullscreen;
+ if(fullScreen)
+ {
+ [NSApp setPresentationOptions:NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationDisableMenuBarTransparency];
+ NSRect rect = [[self screen] frame];
+ rect.origin.y = 0;
+ rect.origin.x = 0;
+ rect.size.height += 22;
+ windowSize = [self frame];
+ [self setMovableByWindowBackground:YES];
+ [self setFrame:rect display:YES animate:YES];
+ [self setFrameOrigin:NSMakePoint(0,100)];
+ }
+ else
+ {
+ [self setFrame:windowSize display:YES animate:YES];
+ [NSApp setPresentationOptions:0];
+ //[[self delegate] windowWillResize:self toSize:[self frame].size];
+ }
+}
+
+- (BOOL) isFullScreen
+{
+ return fullScreen;
+}
+
@end /* EmacsWindow */