emacs-diffs
[Top][All Lists]
Advanced

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

master 75a264e 2/2: General improvements to NS port


From: Alan Third
Subject: master 75a264e 2/2: General improvements to NS port
Date: Sat, 6 Nov 2021 09:00:34 -0400 (EDT)

branch: master
commit 75a264ed023fd407c279eabf4089bb0aa61bec8d
Author: Po Lu <luangruo@yahoo.com>
Commit: Alan Third <alan@idiocy.org>

    General improvements to NS port
    
    * src/dispextern.h: Remove some !HAVE_NS conditionals around grab
    related code.
    * src/frame.c (gui_mouse_grabbed, gui_redo_mouse_highlight): Remove
    !HAVE_NS conditionals around code.
    
    * src/nsmenu.m (ns_update_menubar): Prevent recursive calls and enable
    shallow updates on GNUstep.
    (menuNeedsUpdate): Prevent recursive calls.
    (ns_menu_show): Fix mysterious GC-related bug.
    (update_frame_tool_bar_1): Work around mysterious toolbar sizing bug
    on GNUstep.
    
    * src/nsterm.h (struct ns_output): New field for tracking toolbar
    visibility changes.
    
    * src/nsterm.m (frame_set_mouse_pixel_position): Implement for
    GNUstep.
    (ns_redraw_scroll_bars): Enable for GNUstep.
    (ns_clear_frame): Redraw scrollbars on GNUstep.
    (ns_update_window_end): New function.
    (ns_redisplay_interface): Add ns_update_window_end on GNUstep.
    (- keyDown): Remove debug code that doesn't work on GNUstep.
    (- mouseDown): Enable grab tracking on NS port.
    (- resizeWithOldSuperviewSize): Fix build with NSTRACE.
    
    * src/xdisp.c (note_tab_bar_highlight): Enable some code for NS port.
---
 src/dispextern.h |  2 --
 src/frame.c      |  4 ---
 src/nsmenu.m     | 76 +++++++++++++++++++++++++++++++++++++++++++++-----------
 src/nsterm.h     |  6 +++++
 src/nsterm.m     | 42 +++++++++++++++++++++++++------
 src/xdisp.c      |  2 --
 6 files changed, 102 insertions(+), 30 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index e03e21f..5b28fe7 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3722,10 +3722,8 @@ extern Lisp_Object gui_default_parameter (struct frame 
*, Lisp_Object,
                                           const char *, const char *,
                                           enum resource_types);
 
-#ifndef HAVE_NS /* These both used on W32 and X only.  */
 extern bool gui_mouse_grabbed (Display_Info *);
 extern void gui_redo_mouse_highlight (Display_Info *);
-#endif /* HAVE_NS */
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
diff --git a/src/frame.c b/src/frame.c
index 2b1cb45..79a7c89 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -5028,8 +5028,6 @@ gui_set_no_special_glyphs (struct frame *f, Lisp_Object 
new_value, Lisp_Object o
 }
 
 
-#ifndef HAVE_NS
-
 /* Non-zero if mouse is grabbed on DPYINFO
    and we know the frame where it is.  */
 
@@ -5054,8 +5052,6 @@ gui_redo_mouse_highlight (Display_Info *dpyinfo)
                          dpyinfo->last_mouse_motion_y);
 }
 
-#endif /* HAVE_NS */
-
 /* Subroutines of creating an X frame.  */
 
 /* Make sure that Vx_resource_name is set to a reasonable value.
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 9b78643..29201e6 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -101,6 +101,15 @@ popup_activated (void)
 static void
 ns_update_menubar (struct frame *f, bool deep_p)
 {
+#ifdef NS_IMPL_GNUSTEP
+  static int inside = 0;
+
+  if (inside)
+    return;
+
+  inside++;
+#endif
+
   BOOL needsSet = NO;
   id menu = [NSApp mainMenu];
   bool owfi;
@@ -120,7 +129,12 @@ ns_update_menubar (struct frame *f, bool deep_p)
   NSTRACE ("ns_update_menubar");
 
   if (f != SELECTED_FRAME () || FRAME_EXTERNAL_MENU_BAR (f) == 0)
+    {
+#ifdef NS_IMPL_GNUSTEP
+      inside--;
+#endif
       return;
+    }
   XSETFRAME (Vmenu_updating_frame, f);
 /*fprintf (stderr, "ns_update_menubar: frame: %p\tdeep: %d\tsub: %p\n", f, 
deep_p, submenu); */
 
@@ -144,10 +158,6 @@ ns_update_menubar (struct frame *f, bool deep_p)
   t = -(1000*tb.time+tb.millitm);
 #endif
 
-#ifdef NS_IMPL_GNUSTEP
-  deep_p = 1; /* See comment in menuNeedsUpdate.  */
-#endif
-
   if (deep_p)
     {
       /* Make a widget-value tree representing the entire menu trees.  */
@@ -275,6 +285,9 @@ ns_update_menubar (struct frame *f, bool deep_p)
          free_menubar_widget_value_tree (first_wv);
          discard_menu_items ();
          unbind_to (specpdl_count, Qnil);
+#ifdef NS_IMPL_GNUSTEP
+         inside--;
+#endif
          return;
        }
 
@@ -408,6 +421,10 @@ ns_update_menubar (struct frame *f, bool deep_p)
   if (needsSet)
     [NSApp setMainMenu: menu];
 
+#ifdef NS_IMPL_GNUSTEP
+  inside--;
+#endif
+
   unblock_input ();
 
 }
@@ -452,17 +469,34 @@ set_frame_menubar (struct frame *f, bool deep_p)
    call to ns_update_menubar.  */
 - (void)menuNeedsUpdate: (NSMenu *)menu
 {
+#ifdef NS_IMPL_GNUSTEP
+  static int inside = 0;
+#endif
+
   if (!FRAME_LIVE_P (SELECTED_FRAME ()))
     return;
 
-#ifdef NS_IMPL_COCOA
-/* TODO: GNUstep calls this method when the menu is still being built
-   which results in a recursive stack overflow.  One possible solution
-   is to use menuWillOpen instead, but the Apple docs explicitly warn
-   against changing the contents of the menu in it.  I don't know what
-   the right thing to do for GNUstep is.  */
+#ifdef NS_IMPL_GNUSTEP
+  /* GNUstep calls this method when the menu is still being built
+     which results in a recursive stack overflow, which this variable
+     prevents.  */
+
+  if (!inside)
+    ++inside;
+  else
+    return;
+#endif
+
   if (needsUpdate)
-    ns_update_menubar (SELECTED_FRAME (), true);
+    {
+#ifdef NS_IMPL_GNUSTEP
+      needsUpdate = NO;
+#endif
+      ns_update_menubar (SELECTED_FRAME (), true);
+    }
+
+#ifdef NS_IMPL_GNUSTEP
+  --inside;
 #endif
 }
 
@@ -789,6 +823,9 @@ ns_menu_show (struct frame *f, int x, int y, int menuflags,
 
   p.x = x; p.y = y;
 
+  /* Don't GC due to a mysterious bug.  */
+  inhibit_garbage_collection ();
+
   /* now parse stage 2 as in ns_update_menubar */
   wv = make_widget_value ("contextmenu", NULL, true, Qnil);
   wv->button_type = BUTTON_TYPE_NONE;
@@ -960,15 +997,17 @@ ns_menu_show (struct frame *f, int x, int y, int 
menuflags,
 
   pmenu = [[EmacsMenu alloc] initWithTitle:
                    NILP (title) ? @"" : [NSString stringWithLispString: 
title]];
+  /* On GNUstep, this call makes menu_items nil for whatever reason
+     when displaying a context menu from `context-menu-mode'.  */
+  Lisp_Object items = menu_items;
   [pmenu fillWithWidgetValue: first_wv->contents];
+  menu_items = items;
   free_menubar_widget_value_tree (first_wv);
-  unbind_to (specpdl_count, Qnil);
-
   popup_activated_flag = 1;
   tem = [pmenu runMenuAt: p forFrame: f keymaps: keymaps];
   popup_activated_flag = 0;
   [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
-
+  unbind_to (specpdl_count, Qnil);
   unblock_input ();
   return tem;
 }
@@ -1019,6 +1058,15 @@ update_frame_tool_bar_1 (struct frame *f, EmacsToolbar 
*toolbar)
   [toolbar clearActive];
 #else
   [toolbar clearAll];
+  /* It takes at least 3 such adjustments to fix an issue where the
+     tool bar is 2x too tall when a frame's tool bar is first shown.
+     This is ugly, but I have no other solution for this problem.  */
+  if (FRAME_OUTPUT_DATA (f)->tool_bar_adjusted < 3)
+    {
+      [toolbar setVisible: NO];
+      FRAME_OUTPUT_DATA (f)->tool_bar_adjusted++;
+      [toolbar setVisible: YES];
+    }
 #endif
 
   /* Update EmacsToolbar as in GtkUtils, build items list.  */
diff --git a/src/nsterm.h b/src/nsterm.h
index 944dbd7..8175f99 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -978,6 +978,12 @@ struct ns_output
 
   /* Non-zero if we are doing an animation, e.g. toggling the tool bar.  */
   int in_animation;
+
+#ifdef NS_IMPL_GNUSTEP
+  /* Zero if this is the first time a toolbar has been updated on this
+     frame. */
+  int tool_bar_adjusted;
+#endif
 };
 
 /* This dummy declaration needed to support TTYs.  */
diff --git a/src/nsterm.m b/src/nsterm.m
index a00a58f..9409697 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -65,6 +65,7 @@ GNUstep port and post-20 update by Adrian Robert 
(arobert@cogsci.ucsd.edu)
 
 #ifdef NS_IMPL_GNUSTEP
 #include "process.h"
+#import <GNUstepGUI/GSDisplayServer.h>
 #endif
 
 #ifdef NS_IMPL_COCOA
@@ -2256,13 +2257,19 @@ frame_set_mouse_pixel_position (struct frame *f, int 
pix_x, int pix_y)
 {
   NSTRACE ("frame_set_mouse_pixel_position");
 
-  /* FIXME: what about GNUstep?  */
 #ifdef NS_IMPL_COCOA
   CGPoint mouse_pos =
     CGPointMake(f->left_pos + pix_x,
                 f->top_pos + pix_y +
                 FRAME_NS_TITLEBAR_HEIGHT(f) + FRAME_TOOLBAR_HEIGHT(f));
   CGWarpMouseCursorPosition (mouse_pos);
+#else
+  GSDisplayServer *server = GSServerForWindow ([FRAME_NS_VIEW (f) window]);
+  [server setMouseLocation: NSMakePoint (f->left_pos + pix_x,
+                                        f->top_pos + pix_y
+                                        + FRAME_NS_TITLEBAR_HEIGHT(f)
+                                        + FRAME_TOOLBAR_HEIGHT(f))
+                 onScreen: [[[FRAME_NS_VIEW (f) window] screen] screenNumber]];
 #endif
 }
 
@@ -2575,8 +2582,7 @@ ns_get_shifted_character (NSEvent *event)
    ========================================================================== 
*/
 
 
-#if 0
-/* FIXME: Remove this function. */
+#ifdef NS_IMPL_GNUSTEP
 static void
 ns_redraw_scroll_bars (struct frame *f)
 {
@@ -2621,10 +2627,9 @@ ns_clear_frame (struct frame *f)
   NSRectFill (r);
   ns_unfocus (f);
 
-  /* as of 2006/11 or so this is now needed */
-  /* FIXME: I don't see any reason for this and removing it makes no
-     difference here.  Do we need it for GNUstep?  */
-  //ns_redraw_scroll_bars (f);
+#ifdef NS_IMPL_GNUSTEP
+  ns_redraw_scroll_bars (f);
+#endif
   unblock_input ();
 }
 
@@ -4922,6 +4927,17 @@ ns_default_font_parameter (struct frame *f, Lisp_Object 
parms)
 {
 }
 
+#ifdef NS_IMPL_GNUSTEP
+static void
+ns_update_window_end (struct window *w, bool cursor_on_p,
+                     bool mouse_face_overwritten_p)
+{
+  NSTRACE ("ns_update_window_end (cursor_on_p = %d)", cursor_on_p);
+
+  ns_redraw_scroll_bars (WINDOW_XFRAME (w));
+}
+#endif
+
 /* This and next define (many of the) public functions in this file.  */
 /* gui_* are generic versions in xdisp.c that we, and other terms, get away
          with using despite presence in the "system dependent" redisplay
@@ -4938,7 +4954,11 @@ static struct redisplay_interface ns_redisplay_interface 
=
   ns_scroll_run,
   ns_after_update_window_line,
   NULL, /* update_window_begin */
+#ifndef NS_IMPL_GNUSTEP
   NULL, /* update_window_end   */
+#else
+  ns_update_window_end,
+#endif
   0, /* flush_display */
   gui_clear_window_mouse_face,
   gui_get_glyph_overhangs,
@@ -6165,9 +6185,11 @@ not_in_argv (NSString *arg)
       Lisp_Object kind = fnKeysym ? QCfunction : QCordinary;
       emacs_event->modifiers = EV_MODIFIERS2 (flags, kind);
 
+#ifndef NS_IMPL_GNUSTEP
       if (NS_KEYLOG)
         fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = 
%x\n",
                  code, fnKeysym, flags, emacs_event->modifiers);
+#endif
 
       /* If it was a function key or had control-like modifiers, pass
          it directly to Emacs.  */
@@ -6680,6 +6702,11 @@ not_in_argv (NSString *arg)
       emacs_event->code = EV_BUTTON (theEvent);
       emacs_event->modifiers = EV_MODIFIERS (theEvent)
                              | EV_UDMODIFIERS (theEvent);
+
+      if (emacs_event->modifiers & down_modifier)
+       FRAME_DISPLAY_INFO (emacsframe)->grabbed |= 1 << EV_BUTTON (theEvent);
+      else
+       FRAME_DISPLAY_INFO (emacsframe)->grabbed &= ~(1 << EV_BUTTON 
(theEvent));
     }
 
   XSETINT (emacs_event->x, lrint (p.x));
@@ -6980,7 +7007,6 @@ not_in_argv (NSString *arg)
   height = (int)NSHeight (frame);
 
   NSTRACE_SIZE ("New size", NSMakeSize (width, height));
-  NSTRACE_SIZE ("Original size", size);
 
   /* Reset the frame size to match the bounds of the superview (the
      NSWindow's contentView).  We need to do this as sometimes the
diff --git a/src/xdisp.c b/src/xdisp.c
index 9814efd..86c4e70 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13894,7 +13894,6 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
   clear_mouse_face (hlinfo);
 
   bool mouse_down_p = false;
-#ifndef HAVE_NS
   /* Mouse is down, but on different tab-bar item?  Or alternatively,
      the mouse might've been pressed somewhere we don't know about,
      and then have moved onto the tab bar.  In this case,
@@ -13907,7 +13906,6 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
   if (mouse_down_p && f->last_tab_bar_item != prop_idx
       && f->last_tab_bar_item != -1)
     return;
-#endif
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
 
   /* If tab-bar item is not enabled, don't highlight it.  */



reply via email to

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