xquartz: Rewrite Window menu handling to not depend on X11App.windowsMenu.numberOfItems being correct in -awakeFromNib

Fixes: https://github.com/XQuartz/XQuartz/issues/56
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit fe89c70e47)
This commit is contained in:
Jeremy Huddleston Sequoia 2021-02-18 22:19:21 -08:00
parent b27c6602b3
commit fcbd57367e
1 changed files with 72 additions and 87 deletions

View File

@ -63,7 +63,7 @@ extern char *bundle_id_prefix;
@property (nonatomic, readwrite, strong) NSArray *apps;
@property (nonatomic, readwrite, strong) NSMutableArray *table_apps;
@property (nonatomic, readwrite, assign) NSInteger windows_menu_start;
@property (nonatomic, readwrite, assign) NSInteger windows_menu_nitems;
@property (nonatomic, readwrite, assign) int checked_window_item;
@property (nonatomic, readwrite, assign) x_list *pending_apps;
@property (nonatomic, readwrite, assign) OSX_BOOL finished_launching;
@ -114,8 +114,6 @@ extern char *bundle_id_prefix;
selector: @selector(apps_table_done:)
name: NSWindowWillCloseNotification
object: self.apps_table.window];
self.windows_menu_start = X11App.windowsMenu.numberOfItems;
}
- (void) item_selected:sender
@ -126,77 +124,6 @@ extern char *bundle_id_prefix;
AppleWMWindowMenuItem, [sender tag]);
}
- (void) remove_window_menu
{
NSMenu *menu;
int count, i;
/* Work backwards so we don't mess up the indices */
menu = [X11App windowsMenu];
count = [menu numberOfItems];
for (i = count - 1; i >= self.windows_menu_start; i--)
[menu removeItemAtIndex:i];
NSMenu * const dock_menu = self.dock_menu;
count = [dock_menu indexOfItem:self.dock_window_separator];
for (i = 0; i < count; i++)
[dock_menu removeItemAtIndex:0];
}
- (void) install_window_menu:(NSArray *)list
{
NSMenu *menu;
NSMenuItem *item;
int first, count, i;
menu = [X11App windowsMenu];
first = self.windows_menu_start + 1;
count = [list count];
// Push a Separator
if (count) {
[menu addItem:[NSMenuItem separatorItem]];
}
NSMenu * const dock_menu = self.dock_menu;
for (i = 0; i < count; i++) {
NSString *name, *shortcut;
name = [[list objectAtIndex:i] objectAtIndex:0];
shortcut = [[list objectAtIndex:i] objectAtIndex:1];
if (windowItemModMask == 0 || windowItemModMask == -1)
shortcut = @"";
item =
(NSMenuItem *)[menu addItemWithTitle:name action:
@selector
(item_selected:) keyEquivalent:shortcut];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
item = (NSMenuItem *)[dock_menu insertItemWithTitle:name
action:@selector
(item_selected:) keyEquivalent:shortcut
atIndex:i];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
}
int const checked_window_item = self.checked_window_item;
if (checked_window_item >= 0 && checked_window_item < count) {
item = (NSMenuItem *)[menu itemAtIndex:first + checked_window_item];
[item setState:NSOnState];
item = (NSMenuItem *)[dock_menu itemAtIndex:checked_window_item];
[item setState:NSOnState];
}
}
- (void) remove_apps_menu
{
NSMenu *menu;
@ -282,25 +209,83 @@ extern char *bundle_id_prefix;
- (void) set_window_menu:(NSArray *)list
{
[self remove_window_menu];
[self install_window_menu:list];
NSMenu * const menu = X11App.windowsMenu;
NSMenu * const dock_menu = self.dock_menu;
DarwinSendDDXEvent(kXquartzControllerNotify, 1,
AppleWMWindowMenuNotify);
/* First, remove the existing items from the Window Menu */
NSInteger itemsToRemove = self.windows_menu_nitems;
if (itemsToRemove > 0) {
NSInteger indexForRemoval = menu.numberOfItems - itemsToRemove - 1; /* we also want to remove the separator */
for (NSInteger i = 0 ; i < itemsToRemove + 1 ; i++) {
[menu removeItemAtIndex:indexForRemoval];
}
for (NSInteger i = 0 ; i < itemsToRemove; i++) {
[dock_menu removeItemAtIndex:0];
}
}
NSInteger const itemsToAdd = list.count;
self.windows_menu_nitems = itemsToAdd;
if (itemsToAdd > 0) {
NSMenuItem *item;
// Push a Separator
[menu addItem:[NSMenuItem separatorItem]];
for (NSInteger i = 0; i < itemsToAdd; i++) {
NSString *name, *shortcut;
name = list[i][0];
shortcut = list[i][1];
if (windowItemModMask == 0 || windowItemModMask == -1)
shortcut = @"";
item = (NSMenuItem *)[menu addItemWithTitle:name
action:@selector(item_selected:)
keyEquivalent:shortcut];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
item = (NSMenuItem *)[dock_menu insertItemWithTitle:name
action:@selector(item_selected:)
keyEquivalent:shortcut
atIndex:i];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
}
int const checked_window_item = self.checked_window_item;
if (checked_window_item >= 0 && checked_window_item < itemsToAdd) {
NSInteger first = menu.numberOfItems - itemsToAdd;
item = (NSMenuItem *)[menu itemAtIndex:first + checked_window_item];
[item setState:NSOnState];
item = (NSMenuItem *)[dock_menu itemAtIndex:checked_window_item];
[item setState:NSOnState];
}
}
DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMWindowMenuNotify);
}
- (void) set_window_menu_check:(NSNumber *)nn
{
NSMenu *menu;
NSMenuItem *item;
int first, count;
int n = [nn intValue];
menu = [X11App windowsMenu];
first = self.windows_menu_start + 1;
count = [menu numberOfItems] - first;
NSMenu * const menu = X11App.windowsMenu;
NSMenu * const dock_menu = self.dock_menu;
NSMenuItem *item;
int n = nn.intValue;
NSInteger const count = self.windows_menu_nitems;
NSInteger const first = menu.numberOfItems - count;
int const checked_window_item = self.checked_window_item;
if (checked_window_item >= 0 && checked_window_item < count) {