> What I do is that I keep a checkout from Emacs CVS around and I write,
> test and generate my patches from there.  It's really just a matter of
> "cvs diff -c" then.

Are you able to build a carbonized Emacs from Emacs CVS?

> Strong objection.  That would make the patches much harder to apply to
> any Emacs, and there's no chance of propagating the patch back to GNU
> Emacs.

It is a good point that "manually" maintaining the patches makes it
easier to merge them into Emacs at some point in the future, and
therefore worth the extra pain.

I have attached my current version of the fullscreen patch.  The two
remaining issues are (1) frame resizing when toolbar is turned on or off
in full-screen mode and (2) negative coordinates.

Vebjorn

--~--~---------~--~----~------------~-------~--~----~
Carbon Emacs User Group
http://groups.google.com/group/carbon-emacs?hl=en
-~----------~----~----~----~------~----~------~--~---

diff -Naur -x '*.orig' -x '*.elc' -x emacs -x info ../emacs.orig/src/macterm.c ./src/macterm.c
--- ../emacs.orig/src/macterm.c	2008-05-15 05:35:33.000000000 -0400
+++ ./src/macterm.c	2008-07-16 06:54:33.000000000 -0400
@@ -83,6 +83,8 @@
 
 
 
+int mac_autohide_menubar_on_fullscreen;
+
 /* Non-nil means Emacs uses toolkit scroll bars.  */
 
 Lisp_Object Vx_toolkit_scroll_bars;
@@ -237,6 +239,7 @@
 static void x_update_window_begin P_ ((struct window *));
 static void x_after_update_window_line P_ ((struct glyph_row *));
 
+static CGDirectDisplayID mac_display_id P_ ((WindowRef));
 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
 static void XSetFont P_ ((Display *, GC, XFontStruct *));
 
@@ -4321,6 +4324,19 @@
     }
 
   x_frame_rehighlight (dpyinfo);
+
+  if (frame)
+    {
+      CGDirectDisplayID display = mac_display_id (FRAME_MAC_WINDOW(frame));
+      CGDirectDisplayID main_display = CGMainDisplayID ();
+      if (display == main_display)
+        {
+          if (frame->want_fullscreen == FULLSCREEN_BOTH)
+            SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+          else
+            SetSystemUIMode(kUIModeNormal, 0);
+        }
+    }
 }
 
 /* Handle FocusIn and FocusOut state changes for FRAME.
@@ -5614,6 +5630,12 @@
      register int xoff, yoff;
      int change_gravity;
 {
+  /* Refuse to change one or both offsets if in full-screen mode. */
+  if (f->want_fullscreen & FULLSCREEN_HEIGHT)
+    yoff = f->top_pos;
+  if (f->want_fullscreen & FULLSCREEN_WIDTH)
+    xoff = f->left_pos;
+
   if (change_gravity > 0)
     {
       f->top_pos = yoff;
@@ -5700,6 +5722,7 @@
   BLOCK_INPUT;
 
   check_frame_size (f, &rows, &cols);
+
   f->scroll_bar_actual_width
     = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
 
@@ -5711,6 +5734,17 @@
   f->win_gravity = NorthWestGravity;
   x_wm_set_size_hint (f, (long) 0, 0);
 
+  /* Refuse to change height, width, or both if in full-screen mode. */
+  Rect b;
+  OSStatus st = GetWindowBounds(FRAME_MAC_WINDOW (f), kWindowContentRgn, &b);
+  if (st == noErr)
+    {
+      if (f->want_fullscreen & FULLSCREEN_HEIGHT)
+        pixelheight = b.bottom - b.top;
+      if (f->want_fullscreen & FULLSCREEN_WIDTH)
+        pixelwidth = b.right - b.left;
+    }
+
   mac_size_window (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
 
 #if TARGET_API_MAC_CARBON
@@ -8207,6 +8241,8 @@
 /* Contains the string "reverse", which is a constant for mouse button emu.*/
 Lisp_Object Qreverse;
 
+Lisp_Object Qfullscreen_saved_state;
+
 
 /* Modifier associated with the control key, or nil to ignore. */
 Lisp_Object Vmac_control_modifier;
@@ -9455,6 +9491,220 @@
       bzero (dpyinfo, sizeof (*dpyinfo));
     }
 }
+
+/* Full-screen mode */
+
+static CGDirectDisplayID mac_display_id (wnd)
+     WindowRef wnd;
+{
+  OSStatus s;
+  CGDirectDisplayID display_id;
+    
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+  s = HIWindowGetGreatestAreaDisplay (wnd, kWindowContentRgn,
+                                      kHICoordSpaceScreenPixel, &display_id, 
+                                      NULL);
+  if (s != noErr)
+    return NULL;
+#else
+  GDHandle devh;
+  DisplayIDType id;
+
+  s = GetWindowGreatestAreaDevice (wnd, kWindowContentRgn, &devh, NULL);
+  if (s != noErr)
+    return NULL;
+  OSErr e = DMGetDisplayIDByGDevice (devh, &id, true);
+  if (e != noErr)
+    return NULL;
+  display_id = (CGDirectDisplayID)id;
+#endif
+  return display_id;
+}
+
+#define FNS_kWindowNoTitleBarAttribute 512
+
+extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth;
+
+struct fullscreen_state {
+  int mode, top, bottom, left, right;
+};
+
+static int fullscreen_mode_as_int (symbol)
+     Lisp_Object symbol;
+{
+  CHECK_SYMBOL (symbol);
+  if (EQ (symbol, Qfullwidth))
+    return FULLSCREEN_WIDTH;
+  if (EQ (symbol, Qfullheight))
+    return FULLSCREEN_HEIGHT;
+  if (EQ (symbol, Qfullboth))
+    return FULLSCREEN_BOTH;
+  return FULLSCREEN_NONE;
+}
+
+static Lisp_Object fullscreen_mode_as_symbol (i)
+     int i;
+{
+  Lisp_Object mode = Qnil;
+  switch (i) {
+  case FULLSCREEN_WIDTH: mode = Qfullwidth; break;
+  case FULLSCREEN_HEIGHT: mode = Qfullheight; break;
+  case FULLSCREEN_BOTH: mode = Qfullboth; break;
+  }
+  return mode;
+}
+
+static struct fullscreen_state *
+get_fullscreen_state (f)
+     FRAME_PTR f;
+{
+  struct fullscreen_state *s = xmalloc (sizeof (struct fullscreen_state));
+  s->mode = FULLSCREEN_NONE;
+  s->top = s->left = s->bottom = s->right = INT_MAX;
+  Lisp_Object frame;
+  XSETFRAME (frame, f);
+  Lisp_Object list = Fframe_parameter (frame, Qfullscreen_saved_state);
+  if (Qnil != list)
+    {
+      CHECK_CONS (list);
+      s->mode = fullscreen_mode_as_int (Fcar (list)); 
+      list = Fcdr (list);
+#define POP_NUMBER_OR_NIL(dest, list) do { CHECK_CONS (list); if (Qnil == Fcar (list)) dest = INT_MAX; else { CHECK_NUMBER (Fcar (list)); dest = XINT (Fcar (list)); } list = Fcdr (list); } while (0)
+      POP_NUMBER_OR_NIL (s->top, list);
+      POP_NUMBER_OR_NIL (s->left, list);
+      POP_NUMBER_OR_NIL (s->bottom, list);
+      POP_NUMBER_OR_NIL (s->right, list);
+#undef POP_NUMBER
+    }
+  return s;
+}
+
+static void
+save_fullscreen_state (f, s)
+     FRAME_PTR f;
+     const struct fullscreen_state *s;
+{
+  if (s->mode == FULLSCREEN_NONE)
+    store_frame_param (f, Qfullscreen_saved_state, Qnil);
+  else
+#define NUM(n) n == INT_MAX ? Qnil : make_number (n)
+      store_frame_param (f, Qfullscreen_saved_state, 
+                         list5 (fullscreen_mode_as_symbol (s->mode), 
+                                NUM (s->top), NUM (s->left), NUM (s->bottom),
+                                NUM (s->right)));
+#undef NUM
+}
+
+static pascal void mac_handle_display_reconfiguration (dispID, flags, userInfo)
+     CGDirectDisplayID dispID;
+     CGDisplayChangeSummaryFlags flags;
+     void* userInfo;
+{
+  /* Leave full-screen mode when the display is reconfigured (e.g., a
+     display is added or removed, or the resolution is changed)
+     because it is not obvious whether resizing the window is always
+     the right thing to do. */
+  Lisp_Object frame;
+  XSETFRAME (frame, (FRAME_PTR)userInfo);
+  Fmodify_frame_parameters (frame, list1 (Fcons (Qfullscreen, Qnil)));
+}
+
+static void
+mac_fullscreen_hook (f)
+     FRAME_PTR f;
+{
+  Rect b;
+  OSStatus st;
+     
+  if (f->async_visible)
+    {
+      /* May signal errors, so do before blocking input. */
+      struct fullscreen_state *s = get_fullscreen_state (f);
+
+      BLOCK_INPUT;
+
+      /* Must get the current bounds _before_ removing the title bar,
+         otherwise the window will be too short when restored. */
+      st = GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, &b);
+      if (st != noErr)
+        {
+          UNBLOCK_INPUT;
+          error ("Failed to get current window bounds.");
+        }
+
+      CGDirectDisplayID display = mac_display_id (FRAME_MAC_WINDOW(f));
+      if (!display)
+        {
+          UNBLOCK_INPUT;
+          error ("Failed to get display ID.");
+        }
+      CGDirectDisplayID main_display = CGMainDisplayID ();
+      if ((f->want_fullscreen & FULLSCREEN_BOTH) == FULLSCREEN_BOTH)
+        {
+          ChangeWindowAttributes (FRAME_MAC_WINDOW (f), 
+                                  FNS_kWindowNoTitleBarAttribute,
+                                  kWindowResizableAttribute);
+          if (mac_autohide_menubar_on_fullscreen && display == main_display)
+            SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+        }
+      else
+        {
+          ChangeWindowAttributes (FRAME_MAC_WINDOW (f), 
+                                  kWindowResizableAttribute, 
+                                  FNS_kWindowNoTitleBarAttribute);
+          if (f->want_fullscreen & FULLSCREEN_BOTH)
+            ChangeWindowAttributes (FRAME_MAC_WINDOW (f),
+                                    0, kWindowResizableAttribute);
+          SetSystemUIMode (kUIModeNormal, 0);
+        }
+
+      /* Update the saved state. */
+      int tmp;
+#define SWAP(a, b) tmp = a, a = b, b = tmp
+      if ((f->want_fullscreen ^ s->mode) & FULLSCREEN_WIDTH)
+        SWAP (b.left, s->left), SWAP (b.right, s->right);
+      if ((f->want_fullscreen ^ s->mode) & FULLSCREEN_HEIGHT)
+        SWAP (b.top, s->top), SWAP (b.bottom, s->bottom);
+#undef SWAP
+      s->mode = f->want_fullscreen;
+      save_fullscreen_state (f, s);
+      xfree (s);
+
+      CGRect screen_bounds = CGDisplayBounds (display);
+      if (f->want_fullscreen & FULLSCREEN_HEIGHT)
+        {
+           b.top = (short)screen_bounds.origin.y;
+           b.bottom = b.top + (short)screen_bounds.size.height;
+           b.top += GetMBarHeight();
+        }
+      if (f->want_fullscreen & FULLSCREEN_WIDTH)
+        {
+           b.left = (short)screen_bounds.origin.x;
+           b.right = b.left + (short)screen_bounds.size.width;
+        }
+
+      SetWindowBounds(FRAME_MAC_WINDOW (f), kWindowStructureRgn, &b);
+
+      /* Necessary because x_set_offset and x_set_window_size refuse
+         to change the offset and size of a full-screen frame. */
+      st = GetWindowBounds(FRAME_MAC_WINDOW (f), kWindowContentRgn, &b);
+      if (st == noErr)
+        {
+          mac_handle_size_change (f, b.right - b.left, b.bottom - b.top);
+          mac_handle_origin_change (f);
+        }
+
+      if (f->want_fullscreen & FULLSCREEN_BOTH)
+           CGDisplayRegisterReconfigurationCallback 
+                (mac_handle_display_reconfiguration, f);
+      else
+           CGDisplayRemoveReconfigurationCallback
+                (mac_handle_display_reconfiguration, f);
+
+      UNBLOCK_INPUT;
+      do_pending_window_change(0);
+    }
+}
 
 
 /* Set up use of X before we make the first connection.  */
@@ -9525,6 +9775,7 @@
   condemn_scroll_bars_hook = XTcondemn_scroll_bars;
   redeem_scroll_bar_hook = XTredeem_scroll_bar;
   judge_scroll_bars_hook = XTjudge_scroll_bars;
+  fullscreen_hook = mac_fullscreen_hook;
 
   scroll_region_ok = 1;         /* we'll scroll partial frames */
   char_ins_del_ok = 1;
@@ -9627,6 +9878,9 @@
   staticpro (&Qreverse);
   Qreverse = intern ("reverse");
 
+  staticpro (&Qfullscreen_saved_state);
+  Qfullscreen_saved_state = intern ("fullscreen-saved-state");
+
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;
 
@@ -9765,6 +10019,11 @@
     Fcons (list3 (build_string ("mac-roman"),
 		  make_number (smRoman), Qnil), Qnil);
 
+  DEFVAR_BOOL ("mac-autohide-menubar-on-fullscreen", &mac_autohide_menubar_on_fullscreen,
+	       doc: /* Non-nil means auto-hide the menubar when a frame's fullscreen parameter is 'fullboth. */);
+  mac_autohide_menubar_on_fullscreen = 1;
+
+
 #if USE_MAC_TSM
   DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
     doc: /* Overlay used to display Mac TSM active input area.  */);
diff -Naur -x '*.orig' -x '*.elc' -x emacs -x info ../emacs.orig/src/frame.c ./src/frame.c
--- ../emacs.orig/src/frame.c	2008-01-07 23:30:09.000000000 -0500
+++ ./src/frame.c	2008-07-16 06:46:05.000000000 -0400
@@ -3136,6 +3136,9 @@
   else
     abort ();
 
+  if (fullscreen_hook != NULL) 
+    fullscreen_hook (f);
+
   do_pending_window_change (0);
 
   /* Don't call `face-set-after-frame-default' when faces haven't been

Reply via email to