Author: mlytwyn
Date: Fri May  8 00:40:12 2015
New Revision: 38481

URL: http://svn.gna.org/viewcvs/gnustep?rev=38481&view=rev
Log:
Fix recursion crash on method 'update'

Modified:
    libs/gui/branches/gnustep_testplant_branch/Headers/AppKit/NSMenu.h
    libs/gui/branches/gnustep_testplant_branch/Source/NSMenu.m

Modified: libs/gui/branches/gnustep_testplant_branch/Headers/AppKit/NSMenu.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gui/branches/gnustep_testplant_branch/Headers/AppKit/NSMenu.h?rev=38481&r1=38480&r2=38481&view=diff
==============================================================================
--- libs/gui/branches/gnustep_testplant_branch/Headers/AppKit/NSMenu.h  
(original)
+++ libs/gui/branches/gnustep_testplant_branch/Headers/AppKit/NSMenu.h  Fri May 
 8 00:40:12 2015
@@ -348,7 +348,8 @@
     unsigned int transient: 1;
     unsigned int horizontal: 1;
     unsigned int mainMenuChanged: 1;
-               unsigned int unused: 25;
+    unsigned int isUpdating: 1;
+               unsigned int unused: 24;
   } _menu;
 
 @private

Modified: libs/gui/branches/gnustep_testplant_branch/Source/NSMenu.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/gui/branches/gnustep_testplant_branch/Source/NSMenu.m?rev=38481&r1=38480&r2=38481&view=diff
==============================================================================
--- libs/gui/branches/gnustep_testplant_branch/Source/NSMenu.m  (original)
+++ libs/gui/branches/gnustep_testplant_branch/Source/NSMenu.m  Fri May  8 
00:40:12 2015
@@ -1091,150 +1091,157 @@
 
 - (void) update
 {
-  if (_delegate)
-    {
-      if ([_delegate respondsToSelector:@selector(menuNeedsUpdate:)])
-        {
-          [_delegate menuNeedsUpdate:self];
-        }
-      else if ([_delegate respondsToSelector:@selector(numberOfItemsInMenu:)])
-        {
-          NSInteger num;
-
-          num = [_delegate numberOfItemsInMenu: self];
-          if (num > 0)
+  if (_menu.isUpdating == NO)
+    {
+      _menu.isUpdating = YES;
+      
+      if (_delegate)
+        {
+          if ([_delegate respondsToSelector:@selector(menuNeedsUpdate:)])
             {
-              BOOL cont = YES;
-              NSInteger i = 0;
-              NSInteger curr = [self numberOfItems];
-
-              while (num < curr)
+              [_delegate menuNeedsUpdate:self];
+            }
+          else if ([_delegate 
respondsToSelector:@selector(numberOfItemsInMenu:)])
+            {
+              NSInteger num;
+              
+              num = [_delegate numberOfItemsInMenu: self];
+              if (num > 0)
                 {
-                  [self removeItemAtIndex: --curr];
-                }
-              while (num > curr)
-                {
-                  [self insertItemWithTitle: @"" 
-                        action: NULL
-                        keyEquivalent: @"" 
-                        atIndex: curr++];
-                }
-
-              // FIXME: Should only process the items we display
-              while (cont && i < num)
-                {
-                  cont = [_delegate menu: self
-                                    updateItem: (NSMenuItem*)[self 
itemAtIndex: i]
-                                    atIndex: i
-                                    shouldCancel: NO];
-                  i++;
+                  BOOL cont = YES;
+                  NSInteger i = 0;
+                  NSInteger curr = [self numberOfItems];
+                  
+                  while (num < curr)
+                    {
+                      [self removeItemAtIndex: --curr];
+                    }
+                  while (num > curr)
+                    {
+                      [self insertItemWithTitle: @""
+                                         action: NULL
+                                  keyEquivalent: @""
+                                        atIndex: curr++];
+                    }
+                  
+                  // FIXME: Should only process the items we display
+                  while (cont && i < num)
+                    {
+                      cont = [_delegate menu: self
+                                  updateItem: (NSMenuItem*)[self itemAtIndex: 
i]
+                                     atIndex: i
+                                shouldCancel: NO];
+                      i++;
+                    }
                 }
             }
         }
-    }
-
-  // We use this as a recursion check.
-  if (!_menu.changedMessagesEnabled)
-    return;
-
-  if ([self autoenablesItems])
-    {
-      unsigned i, count;
-
-      count = [_items count];  
       
-      // Temporary disable automatic displaying of menu.
-      [self setMenuChangedMessagesEnabled: NO];
-
-      NS_DURING
-       {
-         for (i = 0; i < count; i++)
-           {
-             NSMenuItem *item = [_items objectAtIndex: i];
-             SEL             action = [item action];
-             id              validator = nil;
-             BOOL            wasEnabled = [item isEnabled];
-             BOOL            shouldBeEnabled;
-
-             // Update the submenu items if any.
-             if ([item hasSubmenu])
-               [[item submenu] update];
-
-             // If there is no action - there can be no validator for the item.
-             if (action)
-               {
-                 validator = [NSApp targetForAction: action 
-                                    to: [item target]
-                                    from: item];
-               }
-             else if (_popUpButtonCell != nil)
-               {
-                 if (NULL != (action = [_popUpButtonCell action]))
-                   {
-                     validator = [NSApp targetForAction: action
-                                        to: [_popUpButtonCell target]
-                                        from: [_popUpButtonCell controlView]];
-                   }
-               }
-
-             if (validator == nil)
-               {
-                 if ((action == NULL) && (_popUpButtonCell != nil))
-                   {
-                     shouldBeEnabled = YES;
-                   }
-                 else 
-                   {
-                     shouldBeEnabled = NO;
-                   }
-               }
-             else if ([validator
-                        respondsToSelector: @selector(validateMenuItem:)])
-               {
-                 shouldBeEnabled = [validator validateMenuItem: item];
-               }
-             else if ([validator
-                        respondsToSelector: 
@selector(validateUserInterfaceItem:)])
-               {
-                 shouldBeEnabled = [validator validateUserInterfaceItem: item];
-               }
-          else if ([item hasSubmenu] && [[item submenu] numberOfItems] == 0)
+      // We use this as a recursion check.
+      if (_menu.changedMessagesEnabled)
+      {
+        if ([self autoenablesItems])
+          {
+            unsigned i, count;
+            
+            count = [_items count];
+            
+            // Temporary disable automatic displaying of menu.
+            [self setMenuChangedMessagesEnabled: NO];
+            
+            NS_DURING
+              {
+                for (i = 0; i < count; i++)
+                  {
+                    NSMenuItem *item = [_items objectAtIndex: i];
+                    SEL              action = [item action];
+                    id       validator = nil;
+                    BOOL             wasEnabled = [item isEnabled];
+                    BOOL             shouldBeEnabled;
+                    
+                    // Update the submenu items if any.
+                    if ([item hasSubmenu])
+                      [[item submenu] update];
+                    
+                    // If there is no action - there can be no validator for 
the item.
+                    if (action)
+                      {
+                        validator = [NSApp targetForAction: action
+                                                        to: [item target]
+                                                      from: item];
+                      }
+                    else if (_popUpButtonCell != nil)
+                      {
+                        if (NULL != (action = [_popUpButtonCell action]))
+                          {
+                            validator = [NSApp targetForAction: action
+                                                            to: 
[_popUpButtonCell target]
+                                                          from: 
[_popUpButtonCell controlView]];
+                          }
+                      }
+                    
+                    if (validator == nil)
+                      {
+                        if ((action == NULL) && (_popUpButtonCell != nil))
+                          {
+                            shouldBeEnabled = YES;
+                          }
+                        else
+                          {
+                            shouldBeEnabled = NO;
+                          }
+                      }
+                    else if ([validator
+                              respondsToSelector: 
@selector(validateMenuItem:)])
+                      {
+                        shouldBeEnabled = [validator validateMenuItem: item];
+                      }
+                    else if ([validator
+                              respondsToSelector: 
@selector(validateUserInterfaceItem:)])
+                      {
+                        shouldBeEnabled = [validator 
validateUserInterfaceItem: item];
+                      }
+                    else if ([item hasSubmenu] && [[item submenu] 
numberOfItems] == 0)
+                      {
+                        shouldBeEnabled = NO;
+                      }
+                    else
+                      {
+                        shouldBeEnabled = YES;
+                      }
+                    
+                    if (shouldBeEnabled != wasEnabled)
+                      {
+                        [item setEnabled: shouldBeEnabled];
+                      }
+                  }
+              }
+            NS_HANDLER
             {
-              shouldBeEnabled = NO;
+              NSLog(@"Error Occurred While Updating Menu %@: %@", [self 
title], localException);
             }
-             else
-               {
-                 shouldBeEnabled = YES;
-               }
-
-             if (shouldBeEnabled != wasEnabled)
-               {
-                 [item setEnabled: shouldBeEnabled];
-               }
-           }
+            NS_ENDHANDLER
+            // Reenable displaying of menus
+            [self setMenuChangedMessagesEnabled: YES]; // this will send 
pending _notifications
           }
-       NS_HANDLER
-         {
-           NSLog(@"Error Occurred While Updating Menu %@: %@", [self title], 
localException);
-         }
-       NS_ENDHANDLER
-      // Reenable displaying of menus
-      [self setMenuChangedMessagesEnabled: YES]; // this will send pending 
_notifications
-    }
-
-  if (_menu.mainMenuChanged)
-    {
-      if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil) == 
NSWindows95InterfaceStyle)
-        {
-          [[GSTheme theme] updateAllWindowsWithMenu: self];
+        
+        if (_menu.mainMenuChanged)
+        {
+          if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil) == 
NSWindows95InterfaceStyle)
+          {
+            [[GSTheme theme] updateAllWindowsWithMenu: self];
+          }
+          _menu.mainMenuChanged = NO;
         }
-      _menu.mainMenuChanged = NO;
-    }
-
-  if (_menu.needsSizing && ([_aWindow isVisible] || [_bWindow isVisible]))
-    {
-      NSDebugLLog (@"NSMenu", @" Calling Size To Fit (A)");
-      [self sizeToFit];
+        
+        if (_menu.needsSizing && ([_aWindow isVisible] || [_bWindow 
isVisible]))
+        {
+          NSDebugLLog (@"NSMenu", @" Calling Size To Fit (A)");
+          [self sizeToFit];
+        }
+      }
+      
+      _menu.isUpdating = NO;
     }
   
   return;


_______________________________________________
Gnustep-cvs mailing list
Gnustep-cvs@gna.org
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to