unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Konstantinos Efstathiou <k-lists@efstathiou.gr>
To: 10014@debbugs.gnu.org
Subject: bug#10014: Patch for fullscreen under Mac OS X 10.7 (Lion)
Date: Thu, 10 Nov 2011 20:05:50 +0100	[thread overview]
Message-ID: <54B660FD-3FC7-4AE8-8CBE-47468155BA6F@efstathiou.gr> (raw)


** Description

The attached patch adds fullscreen support to Cocoa Emacs running under Lion. The fullscreen support works only under OS X 10.7 and takes advantage of the support for fullscreen applications that appeared in this version. In particular the fullscreen window is assigned its own space (here window means Emacs frame).  The patch reuses some code from previous patches that add support for fullscreen under OS X <= 10.6 but were never included in Emacs.

The code works by implementing the fullscreen APIs provided in 10.7, especially the NSWindowDelegate methods windowDidEnterFullScreen:, windowDidExitFullScreen:, and window:willUseFullScreenPresentationOptions:. Furthermore, the Emacs Lisp function ns-toggle-fullscreen is added.

The most potentially dangerous changes are the ones to free_frame_tool_bar and update_frame_tool_bar (in src/nsmenu.m) where the window toolbar is now set to nil in the former function and to [view toolbar] in the latter. Before, only the visibility of the toolbar would change in these functions. This interacted badly with fullscreen support under Lion because when the window would go fullscreen its toolbar would become visible even if it was empty.

One bug that exists is that if one toggles the toolbar visibility while the window is fullscreen, the toolbar stops working properly.

Finally, I have removed the code that was used to add the window size to the window title when the window was resized. This should be determined by appropriately modifying frame-title-format and not by low-level C code because in the latter case this behavior cannot be modified by the user.

** ChangeLog

* lisp/term/ns-win.el, src/nsterm.m, src/nsfns.m, src/nsmenu.m, src/nsterm.h: Add fullscreen support to Cocoa Emacs under Mac OS X 10.7 (Lion).


** Patch

=== modified file 'lisp/term/ns-win.el'
*** lisp/term/ns-win.el	2011-10-01 20:32:01 +0000
--- lisp/term/ns-win.el	2011-11-10 16:22:51 +0000
*************** See the documentation of `create-fontset
*** 928,933 ****
--- 928,937 ----
  (add-to-list 'frame-creation-function-alist '(ns . x-create-frame-with-faces))
  (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)
  

=== modified file 'src/nsfns.m'
*** src/nsfns.m	2011-11-05 12:25:01 +0000
--- src/nsfns.m	2011-11-10 18:54:31 +0000
*************** Value is t if tooltip was open, nil othe
*** 2567,2572 ****
--- 2567,2588 ----
  }
  
  
+ 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);
+ 
+ #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+   [window toggleFullScreen:nil];
+ #endif
+ 
+   return Qnil;
+ }
+ 
+ 
  /* ==========================================================================
  
      Class implementations
*************** be used as the image of the icon represe
*** 2724,2729 ****
--- 2740,2747 ----
    defsubr (&Sx_show_tip);
    defsubr (&Sx_hide_tip);
  
+   defsubr (&Sns_toggle_fullscreen_internal);
+ 
    /* used only in fontset.c */
    check_window_system_func = check_ns;
  

=== modified file 'src/nsmenu.m'
*** src/nsmenu.m	2011-07-29 05:31:12 +0000
--- src/nsmenu.m	2011-11-10 16:22:51 +0000
*************** free_frame_tool_bar (FRAME_PTR f)
*** 986,992 ****
     -------------------------------------------------------------------------- */
  {
    BLOCK_INPUT;
!   [[FRAME_NS_VIEW (f) toolbar] setVisible: NO];
    FRAME_TOOLBAR_HEIGHT (f) = 0;
    UNBLOCK_INPUT;
  }
--- 986,992 ----
     -------------------------------------------------------------------------- */
  {
    BLOCK_INPUT;
!   [[FRAME_NS_VIEW (f) window] setToolbar: nil];
    FRAME_TOOLBAR_HEIGHT (f) = 0;
    UNBLOCK_INPUT;
  }
*************** update_frame_tool_bar (FRAME_PTR f)
*** 1003,1008 ****
--- 1003,1010 ----
    EmacsToolbar *toolbar = [view toolbar];
  
    BLOCK_INPUT;
+   [window setToolbar: toolbar];
+ 
    [toolbar clearActive];
  
    /* update EmacsToolbar as in GtkUtils, build items list */

=== modified file 'src/nsterm.h'
*** src/nsterm.h	2011-09-09 01:06:52 +0000
--- src/nsterm.h	2011-11-10 18:39:22 +0000
*************** along with GNU Emacs.  If not, see <http
*** 38,43 ****
--- 38,46 ----
  #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
  #endif /* NS_IMPL_COCOA */
  
  #ifdef __OBJC__

=== modified file 'src/nsterm.m'
*** src/nsterm.m	2011-11-05 12:25:01 +0000
--- src/nsterm.m	2011-11-10 18:54:02 +0000
*************** ns_term_shutdown (int sig)
*** 5299,5337 ****
  #endif
    if (rows < MINHEIGHT)
      rows = MINHEIGHT;
! #ifdef NS_IMPL_COCOA
!   {
!     /* this sets window title to have size in it; the wm does this under GS */
!     NSRect r = [[self window] frame];
!     if (r.size.height == frameSize.height && r.size.width == frameSize.width)
!       {
!         if (old_title != 0)
!           {
!             xfree (old_title);
!             old_title = 0;
!           }
!       }
!     else
!       {
!         char *size_title;
!         NSWindow *window = [self window];
!         if (old_title == 0)
!           {
!             const char *t = [[[self window] title] UTF8String];
!             char *pos = strstr (t, "  —  ");
!             if (pos)
!               *pos = '\0';
!             old_title = (char *) xmalloc (strlen (t) + 1);
!             strcpy (old_title, t);
!           }
!         size_title = xmalloc (strlen (old_title) + 40);
! 	esprintf (size_title, "%s  —  (%d x %d)", old_title, cols, rows);
!         [window setTitle: [NSString stringWithUTF8String: size_title]];
!         [window display];
!         xfree (size_title);
!       }
!   }
! #endif /* NS_IMPL_COCOA */
  /*fprintf (stderr,"    ...size became %.0f x %.0f  (%d x %d)\n",frameSize.width,frameSize.height,cols,rows); */
  
    return frameSize;
--- 5299,5305 ----
  #endif
    if (rows < MINHEIGHT)
      rows = MINHEIGHT;
! 
  /*fprintf (stderr,"    ...size became %.0f x %.0f  (%d x %d)\n",frameSize.width,frameSize.height,cols,rows); */
  
    return frameSize;
*************** ns_term_shutdown (int sig)
*** 5353,5366 ****
    NSTRACE (windowDidResize);
  /*fprintf (stderr,"windowDidResize: %.0f\n",[theWindow frame].size.height); */
  
- #ifdef NS_IMPL_COCOA
-   if (old_title != 0)
-     {
-       xfree (old_title);
-       old_title = 0;
-     }
- #endif /* NS_IMPL_COCOA */
- 
    /* Avoid loop under GNUstep due to call at beginning of this function.
       (x_set_window_size causes a resize which causes
       a "windowDidResize" which calls x_set_window_size).  */
--- 5321,5326 ----
*************** ns_term_shutdown (int sig)
*** 5388,5393 ****
--- 5348,5407 ----
    ns_send_appdefined (-1);
  }
  
+ #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ - (void)windowDidEnterFullScreen:(NSNotification *)notification
+ {
+     NSTRACE (windowDidEnterFullScreen);
+     /* NSLog(@"Calling windowDidEnterFullScreen"); */
+     
+     NSWindow *window = [self window];
+     NSRect wr = [window frame];
+     int w = (int)wr.size.width - emacsframe->border_width;
+     int h = (int)wr.size.height;
+     cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS(emacsframe, w);
+     rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(emacsframe, h);
+     /* NSLog(@"window_size=%dx%d (%dx%d)", w, h, cols, rows); */
+     FRAME_PIXEL_WIDTH (emacsframe) = w;
+     FRAME_PIXEL_HEIGHT (emacsframe) = h;
+     change_frame_size (emacsframe, rows, cols, 0, 1, 0);
+     SET_FRAME_GARBAGED (emacsframe);
+     cancel_mouse_face (emacsframe);
+     ns_send_appdefined (-1);
+ }
+ #endif
+ 
+ #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ - (void)windowDidExitFullScreen:(NSNotification *)notification
+ {
+     NSTRACE (windowDidExitFullScreen);
+     /* NSLog(@"Calling windowDidExitFullScreen"); */
+     
+     NSWindow *window = [self window];
+     NSRect wr = [window frame];
+     int w = (int)wr.size.width - emacsframe->border_width;
+     int h = (int)wr.size.height
+     - FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
+     - FRAME_TOOLBAR_HEIGHT (emacsframe);
+     cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS(emacsframe, w);
+     rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(emacsframe, h);
+     /* NSLog(@"window_size=%dx%d (%dx%d)", w, h, cols, rows); */
+     FRAME_PIXEL_WIDTH (emacsframe) = w;
+     FRAME_PIXEL_HEIGHT (emacsframe) = h;
+     change_frame_size (emacsframe, rows, cols, 0, 1, 0);
+     SET_FRAME_GARBAGED (emacsframe);
+     cancel_mouse_face (emacsframe);
+     ns_send_appdefined (-1);
+ }
+ #endif
+ 
+ #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ - (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
+ {
+     /* NSLog(@"Calling window:willUseFullScreenPresentationOptions: %d", proposedOptions); */
+     return proposedOptions | NSApplicationPresentationAutoHideToolbar;
+ }
+ #endif
+ 
  
  - (void)windowDidBecomeKey: (NSNotification *)notification
  /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */
*************** ns_term_shutdown (int sig)
*** 5559,5564 ****
--- 5573,5586 ----
    [NSApp registerServicesMenuSendTypes: ns_send_types
                             returnTypes: nil];
  
+ #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+   if (NSApp != nil && [NSApp isActive])
+   {
+     [NSApp setPresentationOptions: NSApplicationPresentationFullScreen | [NSApp presentationOptions] ];
+     [win setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary | [win collectionBehavior] ];
+   }
+ #endif
+ 
    ns_window_num++;
    return self;
  }







                 reply	other threads:[~2011-11-10 19:05 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=54B660FD-3FC7-4AE8-8CBE-47468155BA6F@efstathiou.gr \
    --to=k-lists@efstathiou.gr \
    --cc=10014@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).