mirror of
https://github.com/fltk/fltk.git
synced 2026-05-31 22:04:26 +08:00
macOS: simplify and improve method performKeyEquivalent: of class FLView and fix #1436
Removal of support of very old macOS versions allows to simplify method performKeyEquivalent: of class FLView. This in turn fixes issue #1436. The new code has been tested OK from macOS 10.9 and above.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK).
|
// 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
|
// 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
|
// 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;
|
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 ?
|
// 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();
|
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
|
if (item->visible()) // have the system menu process the shortcut, highlighting the corresponding menu
|
||||||
[[NSApp mainMenu] performKeyEquivalent:[NSApp currentEvent]];
|
[[NSApp mainMenu] performKeyEquivalent:[NSApp currentEvent]];
|
||||||
else // have FLTK process the shortcut associated to an invisible Fl_Menu_Item
|
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) {
|
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].label("Show Previous Tab");
|
||||||
window_menu_items[1].callback(previous_tab_cb);
|
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].label("Show Next Tab");
|
||||||
window_menu_items[2].callback(next_tab_cb);
|
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].label("Move Tab To New Window");
|
||||||
window_menu_items[3].callback(move_tab_cb);
|
window_menu_items[3].callback(move_tab_cb);
|
||||||
window_menu_items[4].label("Merge All Windows");
|
window_menu_items[4].label("Merge All Windows");
|
||||||
|
|||||||
+26
-33
@@ -1483,8 +1483,8 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
|
|||||||
{
|
{
|
||||||
if (fl_mac_os_version >= 101300 && [NSApp isRunning]) [NSApp stop: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();
|
fl_lock_function();
|
||||||
while ( Fl_X::first ) {
|
while ( Fl_X::first ) {
|
||||||
Fl_Window *win = Fl::first_window();
|
Fl_Window *win = Fl::first_window();
|
||||||
@@ -1500,6 +1500,11 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
|
|||||||
Fl::program_should_quit(1);
|
Fl::program_should_quit(1);
|
||||||
Fl_Cocoa_Screen_Driver::breakMacEventLoop(); // necessary when called through menu and in Fl::wait()
|
Fl_Cocoa_Screen_Driver::breakMacEventLoop(); // necessary when called through menu and in Fl::wait()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
|
||||||
|
{
|
||||||
|
attempt_close_all_windows();
|
||||||
return NSTerminateCancel;
|
return NSTerminateCancel;
|
||||||
}
|
}
|
||||||
- (void)applicationDidBecomeActive:(NSNotification *)notify
|
- (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
|
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.
|
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 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)
|
Three sorts of messages are then sent back by the system to myview: doCommandBySelector:, setMarkedText: and insertText:.
|
||||||
when the Ctrl or Cmd modifiers are used. If not, it also calls [[myview inputContext] handleEvent:theEvent].
|
All 3 messages eventually produce Fl::handle(FL_KEYBOARD, win) calls.
|
||||||
The performKeyEquivalent: method returns YES when the keystroke has been handled and NO otherwise, which allows
|
The doCommandBySelector: message allows to process events such as new-line, backward delete, escape, tab.
|
||||||
shortcuts of the system menu to be processed. Three sorts of messages are then sent back by the system to myview:
|
The message setMarkedText: is sent when marked text, that is, temporary text that gets replaced later
|
||||||
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
|
|
||||||
by some other text, is inserted. This happens when a dead key is pressed, and also
|
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
|
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.
|
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();
|
fl_lock_function();
|
||||||
cocoaKeyboardHandler(theEvent);
|
cocoaKeyboardHandler(theEvent);
|
||||||
BOOL handled;
|
|
||||||
Fl_Window *w = [(FLWindow*)[theEvent window] getFl_Window];
|
Fl_Window *w = [(FLWindow*)[theEvent window] getFl_Window];
|
||||||
if ( (mods & NSEventModifierFlagControl) || (mods & NSEventModifierFlagCommand) ) {
|
NSString *s = [theEvent characters];
|
||||||
NSString *s = [theEvent characters];
|
if ( (mods & NSEventModifierFlagShift) && (mods & NSEventModifierFlagCommand) ) {
|
||||||
if ( (mods & NSEventModifierFlagShift) && (mods & NSEventModifierFlagCommand) ) {
|
s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
[FLView prepareEtext:s];
|
||||||
in_key_event = YES;
|
Fl::compose_state = 0;
|
||||||
need_handle = NO;
|
BOOL handled = Fl::handle(FL_KEYBOARD, w);
|
||||||
handled = [[self inputContext] handleEvent:theEvent];
|
if (!handled) {
|
||||||
if (need_handle) handled = Fl::handle(FL_KEYBOARD, w);
|
// detect Ctrl+Command+Space to open character palette, if not used before as shortcut
|
||||||
in_key_event = NO;
|
if ( (mods & NSEventModifierFlagControl) && (mods & NSEventModifierFlagCommand) &&
|
||||||
|
!(mods & (NSEventModifierFlagShift|NSEventModifierFlagOption)) && [pure isEqualToString:@" "] ) {
|
||||||
|
[NSApp orderFrontCharacterPalette:self];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fl_unlock_function();
|
fl_unlock_function();
|
||||||
return handled;
|
return YES;
|
||||||
}
|
}
|
||||||
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent
|
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
@@ -3907,7 +3900,7 @@ static PrintWithTitlebarItem *print_with_titlebar_item = NULL;
|
|||||||
}
|
}
|
||||||
- (void)terminate:(id)sender
|
- (void)terminate:(id)sender
|
||||||
{
|
{
|
||||||
[NSApp terminate:sender];
|
attempt_close_all_windows();
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user