diff --git a/src/Fl_MacOS_Sys_Menu_Bar.mm b/src/Fl_MacOS_Sys_Menu_Bar.mm index f41db31b4..7b6783c66 100644 --- a/src/Fl_MacOS_Sys_Menu_Bar.mm +++ b/src/Fl_MacOS_Sys_Menu_Bar.mm @@ -1,7 +1,7 @@ // // MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2026 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -454,7 +454,10 @@ static int process_sys_menu_shortcuts(int event) if (event != FL_SHORTCUT || !fl_sys_menu_bar || Fl::modal()) return 0; // is the last event the shortcut of an item of the fl_sys_menu_bar menu ? const Fl_Menu_Item *item = fl_sys_menu_bar->menu()->test_shortcut(); - if (!item) return 0; + if (!item) { // It's not a shortcut of the user-part of menubar. Is it of the application menu? + NSMenu *app_menu = [[[NSApp mainMenu] itemAtIndex:0] submenu]; // the application menu + return (int)[app_menu performKeyEquivalent:[NSApp currentEvent]]; + } if (item->visible()) // have the system menu process the shortcut, highlighting the corresponding menu [[NSApp mainMenu] performKeyEquivalent:[NSApp currentEvent]]; else // have FLTK process the shortcut associated to an invisible Fl_Menu_Item @@ -659,10 +662,10 @@ void Fl_MacOS_Sys_Menu_Bar_Driver::create_window_menu(void) if (fl_mac_os_version >= 101200 && window_menu_style() != Fl_Sys_Menu_Bar::tabbing_mode_none) { window_menu_items[1].label("Show Previous Tab"); window_menu_items[1].callback(previous_tab_cb); - window_menu_items[1].shortcut(FL_SHIFT+FL_CTRL+0x9); + window_menu_items[1].shortcut(FL_SHIFT+FL_CTRL+FL_Tab); window_menu_items[2].label("Show Next Tab"); window_menu_items[2].callback(next_tab_cb); - window_menu_items[2].shortcut(FL_CTRL+0x9); + window_menu_items[2].shortcut(FL_CTRL+FL_Tab); window_menu_items[3].label("Move Tab To New Window"); window_menu_items[3].callback(move_tab_cb); window_menu_items[4].label("Merge All Windows"); diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 7df94b879..1f46a7d1c 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -1483,8 +1483,8 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; { if (fl_mac_os_version >= 101300 && [NSApp isRunning]) [NSApp stop:nil]; } -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender -{ + +static void attempt_close_all_windows() { fl_lock_function(); while ( Fl_X::first ) { Fl_Window *win = Fl::first_window(); @@ -1500,6 +1500,11 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; Fl::program_should_quit(1); Fl_Cocoa_Screen_Driver::breakMacEventLoop(); // necessary when called through menu and in Fl::wait() } +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender +{ + attempt_close_all_windows(); return NSTerminateCancel; } - (void)applicationDidBecomeActive:(NSNotification *)notify @@ -2087,14 +2092,12 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi Keyboard input sends keyDown: and performKeyEquivalent: messages to myview. The latter occurs for keys such as ForwardDelete, arrows and F1, and when the Ctrl or Cmd modifiers are used. Other key presses send keyDown: messages. + The performKeyEquivalent: method directly calls Fl::handle(FL_KEYBOARD, focus-window) and returns always YES. The keyDown: method calls [[myview inputContext] handleEvent:theEvent], and triggers system processing of keyboard events. - The performKeyEquivalent: method directly calls Fl::handle(FL_KEYBOARD, focus-window) - when the Ctrl or Cmd modifiers are used. If not, it also calls [[myview inputContext] handleEvent:theEvent]. - The performKeyEquivalent: method returns YES when the keystroke has been handled and NO otherwise, which allows - shortcuts of the system menu to be processed. Three sorts of messages are then sent back by the system to myview: - doCommandBySelector:, setMarkedText: and insertText:. All 3 messages eventually produce Fl::handle(FL_KEYBOARD, win) calls. - The doCommandBySelector: message allows to process events such as new-line, forward and backward delete, arrows, - escape, tab, F1. The message setMarkedText: is sent when marked text, that is, temporary text that gets replaced later + Three sorts of messages are then sent back by the system to myview: doCommandBySelector:, setMarkedText: and insertText:. + All 3 messages eventually produce Fl::handle(FL_KEYBOARD, win) calls. + The doCommandBySelector: message allows to process events such as new-line, backward delete, escape, tab. + The message setMarkedText: is sent when marked text, that is, temporary text that gets replaced later by some other text, is inserted. This happens when a dead key is pressed, and also when entering complex scripts (e.g., Chinese). Fl_Cocoa_Screen_Driver::next_marked_length gives the byte length of marked text before the FL_KEYBOARD event is processed. Fl::compose_state gives this length after this processing. @@ -2327,33 +2330,23 @@ static void cocoaKeyboardHandler(NSEvent *theEvent) } fl_lock_function(); cocoaKeyboardHandler(theEvent); - BOOL handled; Fl_Window *w = [(FLWindow*)[theEvent window] getFl_Window]; - if ( (mods & NSEventModifierFlagControl) || (mods & NSEventModifierFlagCommand) ) { - NSString *s = [theEvent characters]; - if ( (mods & NSEventModifierFlagShift) && (mods & NSEventModifierFlagCommand) ) { - s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit - } - [FLView prepareEtext:s]; - Fl::compose_state = 0; - handled = Fl::handle(FL_KEYBOARD, w); - if (!handled) { - // detect Ctrl+Command+Space to open character palette, if not used before as shortcut - if ( (mods & NSEventModifierFlagControl) && (mods & NSEventModifierFlagCommand) && - !(mods & (NSEventModifierFlagShift|NSEventModifierFlagOption)) && [pure isEqualToString:@" "] ) { - [NSApp orderFrontCharacterPalette:self]; - } - } + NSString *s = [theEvent characters]; + if ( (mods & NSEventModifierFlagShift) && (mods & NSEventModifierFlagCommand) ) { + s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit } - else { - in_key_event = YES; - need_handle = NO; - handled = [[self inputContext] handleEvent:theEvent]; - if (need_handle) handled = Fl::handle(FL_KEYBOARD, w); - in_key_event = NO; + [FLView prepareEtext:s]; + Fl::compose_state = 0; + BOOL handled = Fl::handle(FL_KEYBOARD, w); + if (!handled) { + // detect Ctrl+Command+Space to open character palette, if not used before as shortcut + if ( (mods & NSEventModifierFlagControl) && (mods & NSEventModifierFlagCommand) && + !(mods & (NSEventModifierFlagShift|NSEventModifierFlagOption)) && [pure isEqualToString:@" "] ) { + [NSApp orderFrontCharacterPalette:self]; } + } fl_unlock_function(); - return handled; + return YES; } - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent { @@ -3907,7 +3900,7 @@ static PrintWithTitlebarItem *print_with_titlebar_item = NULL; } - (void)terminate:(id)sender { - [NSApp terminate:sender]; + attempt_close_all_windows(); } @end