diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-13 13:08:05 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-13 13:08:05 +0200 |
commit | 3def602e8b7b6f45003cb95f7a74979118ae0e4a (patch) | |
tree | f7d59c995ba39ee1d57307c4ac74fd02eb046b1c /src | |
parent | 730540332cbeaf949263bdf5dae5714688f0d10a (diff) |
macOS: Disable page navigation while editing text
The Cmd+Left/Right keys used both for page navigation (by default) and for moving the cursor inside text editor. The input widget keys should take precedence.
Diffstat (limited to 'src')
-rw-r--r-- | src/macos.h | 2 | ||||
-rw-r--r-- | src/macos.m | 77 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 18 |
3 files changed, 82 insertions, 15 deletions
diff --git a/src/macos.h b/src/macos.h index f948a0db..a59351e6 100644 --- a/src/macos.h +++ b/src/macos.h | |||
@@ -33,4 +33,6 @@ void registerURLHandler_MacOS (void); | |||
33 | void setupApplication_MacOS (void); | 33 | void setupApplication_MacOS (void); |
34 | void insertMenuItems_MacOS (const char *menuLabel, int atIndex, const iMenuItem *items, size_t count); | 34 | void insertMenuItems_MacOS (const char *menuLabel, int atIndex, const iMenuItem *items, size_t count); |
35 | void enableMenu_MacOS (const char *menuLabel, iBool enable); | 35 | void enableMenu_MacOS (const char *menuLabel, iBool enable); |
36 | void enableMenuItem_MacOS (const char *menuItemCommand, iBool enable); | ||
37 | void enableMenuItemsByKey_MacOS (int key, int kmods, iBool enable); | ||
36 | void handleCommand_MacOS (const char *cmd); | 38 | void handleCommand_MacOS (const char *cmd); |
diff --git a/src/macos.m b/src/macos.m index c8793eac..4e214923 100644 --- a/src/macos.m +++ b/src/macos.m | |||
@@ -367,40 +367,86 @@ void enableMenu_MacOS(const char *menuLabel, iBool enable) { | |||
367 | [label release]; | 367 | [label release]; |
368 | } | 368 | } |
369 | 369 | ||
370 | static void setShortcut_NSMenuItem_(NSMenuItem *item, int key, int kmods) { | 370 | void enableMenuItem_MacOS(const char *menuItemCommand, iBool enable) { |
371 | iString str; | 371 | NSApplication *app = [NSApplication sharedApplication]; |
372 | init_String(&str); | 372 | NSMenu *appMenu = [app mainMenu]; |
373 | MyDelegate *myDel = (MyDelegate *) app.delegate; | ||
374 | for (NSMenuItem *mainMenuItem in appMenu.itemArray) { | ||
375 | NSMenu *menu = mainMenuItem.submenu; | ||
376 | if (menu) { | ||
377 | for (NSMenuItem *menuItem in menu.itemArray) { | ||
378 | NSString *command = [myDel commandForItem:menuItem]; | ||
379 | if (command) { | ||
380 | if (!iCmpStr([command cStringUsingEncoding:NSUTF8StringEncoding], | ||
381 | menuItemCommand)) { | ||
382 | [menuItem setEnabled:enable]; | ||
383 | return; | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | |||
391 | static iString *composeKeyEquivalent_(int key, int kmods, NSEventModifierFlags *modMask) { | ||
392 | iString *str = new_String(); | ||
373 | if (key == SDLK_LEFT) { | 393 | if (key == SDLK_LEFT) { |
374 | appendChar_String(&str, 0x2190); | 394 | appendChar_String(str, 0x2190); |
375 | } | 395 | } |
376 | else if (key == SDLK_RIGHT) { | 396 | else if (key == SDLK_RIGHT) { |
377 | appendChar_String(&str, 0x2192); | 397 | appendChar_String(str, 0x2192); |
378 | } | 398 | } |
379 | else if (key == SDLK_UP) { | 399 | else if (key == SDLK_UP) { |
380 | appendChar_String(&str, 0x2191); | 400 | appendChar_String(str, 0x2191); |
381 | } | 401 | } |
382 | else if (key == SDLK_DOWN) { | 402 | else if (key == SDLK_DOWN) { |
383 | appendChar_String(&str, 0x2193); | 403 | appendChar_String(str, 0x2193); |
384 | } | 404 | } |
385 | else if (key) { | 405 | else if (key) { |
386 | appendChar_String(&str, key); | 406 | appendChar_String(str, key); |
387 | } | 407 | } |
388 | NSEventModifierFlags modMask = 0; | 408 | *modMask = 0; |
389 | if (kmods & KMOD_GUI) { | 409 | if (kmods & KMOD_GUI) { |
390 | modMask |= NSEventModifierFlagCommand; | 410 | *modMask |= NSEventModifierFlagCommand; |
391 | } | 411 | } |
392 | if (kmods & KMOD_ALT) { | 412 | if (kmods & KMOD_ALT) { |
393 | modMask |= NSEventModifierFlagOption; | 413 | *modMask |= NSEventModifierFlagOption; |
394 | } | 414 | } |
395 | if (kmods & KMOD_CTRL) { | 415 | if (kmods & KMOD_CTRL) { |
396 | modMask |= NSEventModifierFlagControl; | 416 | *modMask |= NSEventModifierFlagControl; |
397 | } | 417 | } |
398 | if (kmods & KMOD_SHIFT) { | 418 | if (kmods & KMOD_SHIFT) { |
399 | modMask |= NSEventModifierFlagShift; | 419 | *modMask |= NSEventModifierFlagShift; |
400 | } | 420 | } |
421 | return str; | ||
422 | } | ||
423 | |||
424 | void enableMenuItemsByKey_MacOS(int key, int kmods, iBool enable) { | ||
425 | NSApplication *app = [NSApplication sharedApplication]; | ||
426 | NSMenu *appMenu = [app mainMenu]; | ||
427 | NSEventModifierFlags modMask; | ||
428 | iString *keyEquiv = composeKeyEquivalent_(key, kmods, &modMask); | ||
429 | for (NSMenuItem *mainMenuItem in appMenu.itemArray) { | ||
430 | NSMenu *menu = mainMenuItem.submenu; | ||
431 | if (menu) { | ||
432 | for (NSMenuItem *menuItem in menu.itemArray) { | ||
433 | if (menuItem.keyEquivalentModifierMask == modMask && | ||
434 | !iCmpStr([menuItem.keyEquivalent cStringUsingEncoding:NSUTF8StringEncoding], | ||
435 | cstr_String(keyEquiv))) { | ||
436 | [menuItem setEnabled:enable]; | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | delete_String(keyEquiv); | ||
442 | } | ||
443 | |||
444 | static void setShortcut_NSMenuItem_(NSMenuItem *item, int key, int kmods) { | ||
445 | NSEventModifierFlags modMask; | ||
446 | iString *str = composeKeyEquivalent_(key, kmods, &modMask); | ||
401 | [item setKeyEquivalentModifierMask:modMask]; | 447 | [item setKeyEquivalentModifierMask:modMask]; |
402 | [item setKeyEquivalent:[NSString stringWithUTF8String:cstr_String(&str)]]; | 448 | [item setKeyEquivalent:[NSString stringWithUTF8String:cstr_String(str)]]; |
403 | deinit_String(&str); | 449 | delete_String(str); |
404 | } | 450 | } |
405 | 451 | ||
406 | void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem *items, size_t count) { | 452 | void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem *items, size_t count) { |
@@ -412,6 +458,7 @@ void insertMenuItems_MacOS(const char *menuLabel, int atIndex, const iMenuItem * | |||
412 | keyEquivalent:@"" | 458 | keyEquivalent:@"" |
413 | atIndex:atIndex]; | 459 | atIndex:atIndex]; |
414 | NSMenu *menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:menuLabel]]; | 460 | NSMenu *menu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:menuLabel]]; |
461 | [menu setAutoenablesItems:NO]; | ||
415 | for (size_t i = 0; i < count; ++i) { | 462 | for (size_t i = 0; i < count; ++i) { |
416 | const char *label = items[i].label; | 463 | const char *label = items[i].label; |
417 | if (label[0] == '\r') { | 464 | if (label[0] == '\r') { |
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 59608151..c4c7475e 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -30,9 +30,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
30 | #include <SDL_clipboard.h> | 30 | #include <SDL_clipboard.h> |
31 | #include <SDL_timer.h> | 31 | #include <SDL_timer.h> |
32 | 32 | ||
33 | #if defined (iPlatformApple) | ||
34 | # include "macos.h" | ||
35 | #endif | ||
36 | |||
33 | static const int refreshInterval_InputWidget_ = 256; | 37 | static const int refreshInterval_InputWidget_ = 256; |
34 | static const size_t maxUndo_InputWidget_ = 64; | 38 | static const size_t maxUndo_InputWidget_ = 64; |
35 | 39 | ||
40 | static void enableEditorKeysInMenus_(iBool enable) { | ||
41 | #if defined (iPlatformApple) | ||
42 | enableMenuItemsByKey_MacOS(SDLK_LEFT, KMOD_PRIMARY, enable); | ||
43 | enableMenuItemsByKey_MacOS(SDLK_RIGHT, KMOD_PRIMARY, enable); | ||
44 | #else | ||
45 | iUnused(enable); | ||
46 | #endif | ||
47 | } | ||
48 | |||
36 | iDeclareType(InputUndo) | 49 | iDeclareType(InputUndo) |
37 | 50 | ||
38 | struct Impl_InputUndo { | 51 | struct Impl_InputUndo { |
@@ -114,6 +127,9 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) { | |||
114 | } | 127 | } |
115 | 128 | ||
116 | void deinit_InputWidget(iInputWidget *d) { | 129 | void deinit_InputWidget(iInputWidget *d) { |
130 | if (isSelected_Widget(d)) { | ||
131 | enableEditorKeysInMenus_(iTrue); | ||
132 | } | ||
117 | delete_TextBuf(d->buffered); | 133 | delete_TextBuf(d->buffered); |
118 | clearUndo_InputWidget_(d); | 134 | clearUndo_InputWidget_(d); |
119 | deinit_Array(&d->undoStack); | 135 | deinit_Array(&d->undoStack); |
@@ -279,6 +295,7 @@ void begin_InputWidget(iInputWidget *d) { | |||
279 | else { | 295 | else { |
280 | iZap(d->mark); | 296 | iZap(d->mark); |
281 | } | 297 | } |
298 | enableEditorKeysInMenus_(iFalse); | ||
282 | } | 299 | } |
283 | 300 | ||
284 | void end_InputWidget(iInputWidget *d, iBool accept) { | 301 | void end_InputWidget(iInputWidget *d, iBool accept) { |
@@ -287,6 +304,7 @@ void end_InputWidget(iInputWidget *d, iBool accept) { | |||
287 | /* Was not active. */ | 304 | /* Was not active. */ |
288 | return; | 305 | return; |
289 | } | 306 | } |
307 | enableEditorKeysInMenus_(iTrue); | ||
290 | if (!accept) { | 308 | if (!accept) { |
291 | setCopy_Array(&d->text, &d->oldText); | 309 | setCopy_Array(&d->text, &d->oldText); |
292 | } | 310 | } |