emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 16e4bd5 2/4: Merge from origin/emacs-25


From: Paul Eggert
Subject: [Emacs-diffs] master 16e4bd5 2/4: Merge from origin/emacs-25
Date: Wed, 23 Mar 2016 18:29:30 +0000

branch: master
commit 16e4bd52e3119d4905de02d33f1cc134498cb0b6
Merge: 70c7a51 e643977
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Merge from origin/emacs-25
    
    e643977 Make `toggle-frame-maximized' respect the dock on OS X (bug#2...
    38a43f1 Fix bug in displaying header line with a box face
---
 src/nsterm.m |  142 +++++++++++++++++++++++++++++++++++++++++++++++++---------
 src/xdisp.c  |   61 +++++++++++++++++++------
 2 files changed, 167 insertions(+), 36 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index b796193..4048ac4 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -646,42 +646,129 @@ ns_release_autorelease_pool (void *pool)
 }
 
 
-/* True, if the menu bar should be hidden.  */
-
 static BOOL
 ns_menu_bar_should_be_hidden (void)
+/* True, if the menu bar should be hidden.  */
 {
   return !NILP (ns_auto_hide_menu_bar)
     && [NSApp respondsToSelector:@selector(setPresentationOptions:)];
 }
 
 
-static CGFloat
-ns_menu_bar_height (NSScreen *screen)
-/* The height of the menu bar, if visible.
+struct EmacsMargins
+{
+  CGFloat top;
+  CGFloat bottom;
+  CGFloat left;
+  CGFloat right;
+};
 
-   Note: Don't use this when fullscreen is enabled -- the screen
-   sometimes includes, sometimes excludes the menu bar area. */
+
+static struct EmacsMargins
+ns_screen_margins (NSScreen *screen)
+/* The parts of SCREEN used by the operating system.  */
 {
-  CGFloat res;
+  NSTRACE ("ns_screen_margins");
+
+  struct EmacsMargins margins;
+
+  NSRect screenFrame = [screen frame];
+  NSRect screenVisibleFrame = [screen visibleFrame];
 
+  /* Sometimes, visibleFrame isn't up-to-date with respect to a hidden
+     menu bar, check this explicitly.  */
   if (ns_menu_bar_should_be_hidden())
     {
-      res = 0;
+      margins.top = 0;
     }
   else
     {
-      NSRect screenFrame = [screen frame];
-      NSRect screenVisibleFrame = [screen visibleFrame];
-
       CGFloat frameTop = screenFrame.origin.y + screenFrame.size.height;
       CGFloat visibleFrameTop = (screenVisibleFrame.origin.y
                                  + screenVisibleFrame.size.height);
 
-      res = frameTop - visibleFrameTop;
+      margins.top = frameTop - visibleFrameTop;
+    }
+
+  {
+    CGFloat frameRight = screenFrame.origin.x + screenFrame.size.width;
+    CGFloat visibleFrameRight = (screenVisibleFrame.origin.x
+                                 + screenVisibleFrame.size.width);
+    margins.right = frameRight - visibleFrameRight;
+  }
+
+  margins.bottom = screenVisibleFrame.origin.y - screenFrame.origin.y;
+  margins.left   = screenVisibleFrame.origin.x - screenFrame.origin.x;
 
+  NSTRACE_MSG ("left:%g right:%g top:%g bottom:%g",
+               margins.left,
+               margins.right,
+               margins.top,
+               margins.bottom);
+
+  return margins;
+}
+
+
+/* A screen margin between 1 and DOCK_IGNORE_LIMIT (inclusive) is
+   assumed to contain a hidden dock.  OS X currently use 4 pixels for
+   this, however, to be future compatible, a larger value is used.  */
+#define DOCK_IGNORE_LIMIT 6
+
+static struct EmacsMargins
+ns_screen_margins_ignoring_hidden_dock (NSScreen *screen)
+/* The parts of SCREEN used by the operating system, excluding the parts
+reserved for an hidden dock.  */
+{
+  NSTRACE ("ns_screen_margins_ignoring_hidden_dock");
+
+  struct EmacsMargins margins = ns_screen_margins(screen);
+
+  /* OS X (currently) reserved 4 pixels along the edge where a hidden
+     dock is located.  Unfortunately, it's not possible to find the
+     location and information about if the dock is hidden.  Instead,
+     it is assumed that if the margin of an edge is less than
+     DOCK_IGNORE_LIMIT, it contains a hidden dock.  */
+  if (margins.left <= DOCK_IGNORE_LIMIT)
+    {
+      margins.left = 0;
+    }
+  if (margins.right <= DOCK_IGNORE_LIMIT)
+    {
+      margins.right = 0;
+    }
+  if (margins.top <= DOCK_IGNORE_LIMIT)
+    {
+      margins.top = 0;
+    }
+  /* Note: This doesn't occur in current versions of OS X, but
+     included for completeness and future compatibility.  */
+  if (margins.bottom <= DOCK_IGNORE_LIMIT)
+    {
+      margins.bottom = 0;
     }
 
+  NSTRACE_MSG ("left:%g right:%g top:%g bottom:%g",
+               margins.left,
+               margins.right,
+               margins.top,
+               margins.bottom);
+
+  return margins;
+}
+
+
+static CGFloat
+ns_menu_bar_height (NSScreen *screen)
+/* The height of the menu bar, if visible.
+
+   Note: Don't use this when fullscreen is enabled -- the screen
+   sometimes includes, sometimes excludes the menu bar area.  */
+{
+  struct EmacsMargins margins = ns_screen_margins(screen);
+
+  CGFloat res = margins.top;
+
   NSTRACE ("ns_menu_bar_height " NSTRACE_FMT_RETURN " %.0f", res);
 
   return res;
@@ -7867,9 +7954,10 @@ not_in_argv (NSString *arg)
   // the menu-bar.
   [super zoom:sender];
 
-#elsif 0
+#elif 0
   // Native zoom done using the standard zoom animation, plus an
-  // explicit resize to cover the full screen.
+  // explicit resize to cover the full screen, except the menu-bar and
+  // dock, if present.
   [super zoom:sender];
 
   // After the native zoom, resize the resulting frame to fill the
@@ -7889,6 +7977,9 @@ not_in_argv (NSString *arg)
       NSTRACE_FSTYPE ("fullscreenState", fs_state);
 
       NSRect sr = [screen frame];
+      struct EmacsMargins margins
+        = ns_screen_margins_ignoring_hidden_dock(screen);
+
       NSRect wr = [self frame];
       NSTRACE_RECT ("Rect after zoom", wr);
 
@@ -7897,15 +7988,15 @@ not_in_argv (NSString *arg)
       if (fs_state == FULLSCREEN_MAXIMIZED
           || fs_state == FULLSCREEN_HEIGHT)
         {
-          newWr.origin.x = 0;
-          newWr.size.height = sr.size.height - ns_menu_bar_height(screen);
+          newWr.origin.y = sr.origin.y + margins.bottom;
+          newWr.size.height = sr.size.height - margins.top - margins.bottom;
         }
 
       if (fs_state == FULLSCREEN_MAXIMIZED
           || fs_state == FULLSCREEN_WIDTH)
         {
-          newWr.origin.y = 0;
-          newWr.size.width = sr.size.width;
+          newWr.origin.x = sr.origin.x + margins.left;
+          newWr.size.width = sr.size.width - margins.right - margins.left;
         }
 
       if (newWr.size.width     != wr.size.width
@@ -7918,13 +8009,20 @@ not_in_argv (NSString *arg)
         }
     }
 #else
-  // Non-native zoom which is done instantaneously.  The resulting frame
-  // covers the entire screen, except the menu-bar, if present.
+  // Non-native zoom which is done instantaneously.  The resulting
+  // frame covers the entire screen, except the menu-bar and dock, if
+  // present.
   NSScreen * screen = [self screen];
   if (screen != nil)
     {
       NSRect sr = [screen frame];
-      sr.size.height -= ns_menu_bar_height (screen);
+      struct EmacsMargins margins
+        = ns_screen_margins_ignoring_hidden_dock(screen);
+
+      sr.size.height -= (margins.top + margins.bottom);
+      sr.size.width  -= (margins.left + margins.right);
+      sr.origin.x += margins.left;
+      sr.origin.y += margins.bottom;
 
       sr = [[self delegate] windowWillUseStandardFrame:self
                                           defaultFrame:sr];
diff --git a/src/xdisp.c b/src/xdisp.c
index 7dc99e1..254b97b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -7229,18 +7229,21 @@ get_next_display_element (struct it *it)
                {
                  ptrdiff_t ignore;
                  int next_face_id;
+                 bool text_from_string = false;
+                 /* Normally, the next buffer location is stored in
+                    IT->current.pos...  */
                  struct text_pos pos = it->current.pos;
 
-                 /* For a string from a display property, the next
-                    buffer position is stored in the 'position'
+                 /* ...but for a string from a display property, the
+                    next buffer position is stored in the 'position'
                     member of the iteration stack slot below the
                     current one, see handle_single_display_spec.  By
-                    contrast, it->current.pos was not yet updated
-                    to point to that buffer position; that will
-                    happen in pop_it, after we finish displaying the
-                    current string.  Note that we already checked
-                    above that it->sp is positive, so subtracting one
-                    from it is safe.  */
+                    contrast, it->current.pos was not yet updated to
+                    point to that buffer position; that will happen
+                    in pop_it, after we finish displaying the current
+                    string.  Note that we already checked above that
+                    it->sp is positive, so subtracting one from it is
+                    safe.  */
                  if (it->from_disp_prop_p)
                    {
                      int stackp = it->sp - 1;
@@ -7249,19 +7252,49 @@ get_next_display_element (struct it *it)
                      while (stackp >= 0
                             && STRINGP ((it->stack + stackp)->string))
                        stackp--;
-                     eassert (stackp >= 0);
-                     pos = (it->stack + stackp)->position;
+                     if (stackp < 0)
+                       {
+                         /* If no stack slot was found for iterating
+                            a buffer, we are displaying text from a
+                            string, most probably the mode line or
+                            the header line, and that string has a
+                            display string on some of its
+                            characters.  */
+                         text_from_string = true;
+                         pos = it->stack[it->sp - 1].position;
+                       }
+                     else
+                       pos = (it->stack + stackp)->position;
                    }
                  else
                    INC_TEXT_POS (pos, it->multibyte_p);
 
-                 if (CHARPOS (pos) >= ZV)
+                 if (text_from_string)
+                   {
+                     Lisp_Object base_string = it->stack[it->sp - 1].string;
+
+                     if (CHARPOS (pos) >= SCHARS (base_string) - 1)
+                       it->end_of_box_run_p = true;
+                     else
+                       {
+                         next_face_id
+                           = face_at_string_position (it->w, base_string,
+                                                      CHARPOS (pos), 0,
+                                                      &ignore, face_id, false);
+                         it->end_of_box_run_p
+                           = (FACE_FROM_ID (it->f, next_face_id)->box
+                              == FACE_NO_BOX);
+                       }
+                   }
+                 else if (CHARPOS (pos) >= ZV)
                    it->end_of_box_run_p = true;
                  else
                    {
-                     next_face_id = face_at_buffer_position
-                       (it->w, CHARPOS (pos), &ignore,
-                        CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, false, -1);
+                     next_face_id =
+                       face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
+                                                CHARPOS (pos)
+                                                + TEXT_PROP_DISTANCE_LIMIT,
+                                                false, -1);
                      it->end_of_box_run_p
                        = (FACE_FROM_ID (it->f, next_face_id)->box
                           == FACE_NO_BOX);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]