diff --git a/src/Build/Include/Makefile.inc b/src/Build/Include/Makefile.inc index be534871..f947f9dc 100644 --- a/src/Build/Include/Makefile.inc +++ b/src/Build/Include/Makefile.inc @@ -51,7 +51,13 @@ clean: %.o: %.cpp @echo Compiling $(GetWindowStyle() & wxTE_PASSWORD)) { wxTextCtrl* passwordCtrl = (wxTextCtrl*) focusedCtrl; - if (event.GetId() == g_customIdCmdV) + if (isPasteShortcut) passwordCtrl->Paste (); - else if (event.GetId() == g_customIdCmdA) + else if (isSelectAllShortcut) passwordCtrl->SelectAll (); bHandled = true; } diff --git a/src/Main/MacOSXSecureTextFieldHotkeys.h b/src/Main/MacOSXSecureTextFieldHotkeys.h new file mode 100644 index 00000000..c0316b66 --- /dev/null +++ b/src/Main/MacOSXSecureTextFieldHotkeys.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2013-2025 AM Crypto. All rights reserved. + + Governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Main_MacOSXSecureTextFieldHotkeys +#define TC_HEADER_Main_MacOSXSecureTextFieldHotkeys + +#ifdef TC_MACOSX +namespace VeraCrypt +{ + void InstallMacOSXSecureTextFieldHotkeys (); + void UninstallMacOSXSecureTextFieldHotkeys (); +} +#endif + +#endif // TC_HEADER_Main_MacOSXSecureTextFieldHotkeys diff --git a/src/Main/MacOSXSecureTextFieldHotkeys.mm b/src/Main/MacOSXSecureTextFieldHotkeys.mm new file mode 100644 index 00000000..f7a0a8fd --- /dev/null +++ b/src/Main/MacOSXSecureTextFieldHotkeys.mm @@ -0,0 +1,114 @@ +/* + Copyright (c) 2013-2025 AM Crypto. All rights reserved. + + Governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "System.h" +#include "MacOSXSecureTextFieldHotkeys.h" + +#ifdef TC_MACOSX +#import + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if defined(MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12 +#define VC_NSEVENT_MASK_KEY_DOWN NSEventMaskKeyDown +#define VC_NSEVENT_MODIFIER_FLAG_COMMAND NSEventModifierFlagCommand +#define VC_NSEVENT_MODIFIER_FLAG_CONTROL NSEventModifierFlagControl +#define VC_NSEVENT_MODIFIER_FLAG_OPTION NSEventModifierFlagOption +#define VC_NSEVENT_MODIFIER_FLAG_SHIFT NSEventModifierFlagShift +#define VC_NSEVENT_TYPE_KEY_DOWN NSEventTypeKeyDown +#else +#define VC_NSEVENT_MASK_KEY_DOWN NSKeyDownMask +#define VC_NSEVENT_MODIFIER_FLAG_COMMAND NSCommandKeyMask +#define VC_NSEVENT_MODIFIER_FLAG_CONTROL NSControlKeyMask +#define VC_NSEVENT_MODIFIER_FLAG_OPTION NSAlternateKeyMask +#define VC_NSEVENT_MODIFIER_FLAG_SHIFT NSShiftKeyMask +#define VC_NSEVENT_TYPE_KEY_DOWN NSKeyDown +#endif + +namespace +{ + id SecureTextFieldHotkeyMonitor = nil; + + bool IsCommandA (NSEvent *event) + { + if ([event type] != VC_NSEVENT_TYPE_KEY_DOWN) + return false; + + const NSEventModifierFlags shortcutModifiers = + VC_NSEVENT_MODIFIER_FLAG_COMMAND | VC_NSEVENT_MODIFIER_FLAG_CONTROL | VC_NSEVENT_MODIFIER_FLAG_OPTION | VC_NSEVENT_MODIFIER_FLAG_SHIFT; + + if (([event modifierFlags] & shortcutModifiers) != VC_NSEVENT_MODIFIER_FLAG_COMMAND) + return false; + + NSString *characters = [event charactersIgnoringModifiers]; + if ([characters length] != 1) + return false; + + unichar character = [characters characterAtIndex:0]; + return character == 'a' || character == 'A'; + } + + wxTextCtrl *GetFocusedSecureTextCtrl () + { + wxWindow *focusedCtrl = wxWindow::FindFocus(); + if (!focusedCtrl + || !focusedCtrl->IsKindOf (wxCLASSINFO (wxTextCtrl)) + || !(focusedCtrl->GetWindowStyle() & wxTE_PASSWORD)) + { + return nullptr; + } + + return static_cast (focusedCtrl); + } + + NSEvent *HandleSecureTextFieldHotkey (NSEvent *event) + { + if (!IsCommandA (event)) + return event; + + wxTextCtrl *secureTextCtrl = GetFocusedSecureTextCtrl(); + if (!secureTextCtrl) + return event; + + secureTextCtrl->SelectAll(); + return nil; + } +} + +namespace VeraCrypt +{ + void InstallMacOSXSecureTextFieldHotkeys () + { + if (SecureTextFieldHotkeyMonitor) + return; + + SecureTextFieldHotkeyMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:VC_NSEVENT_MASK_KEY_DOWN handler:^NSEvent *(NSEvent *event) { + return HandleSecureTextFieldHotkey (event); + }]; +#if !__has_feature(objc_arc) + [SecureTextFieldHotkeyMonitor retain]; +#endif + } + + void UninstallMacOSXSecureTextFieldHotkeys () + { + if (!SecureTextFieldHotkeyMonitor) + return; + + id monitor = SecureTextFieldHotkeyMonitor; + SecureTextFieldHotkeyMonitor = nil; + + [NSEvent removeMonitor:monitor]; +#if !__has_feature(objc_arc) + [monitor release]; +#endif + } +} +#endif diff --git a/src/Main/Main.make b/src/Main/Main.make index 043c157f..2747f63b 100755 --- a/src/Main/Main.make +++ b/src/Main/Main.make @@ -26,6 +26,9 @@ OBJS += Resources.o ifndef TC_NO_GUI OBJS += FatalErrorHandler.o OBJS += GraphicUserInterface.o +ifeq "$(PLATFORM)" "MacOSX" +OBJS += MacOSXSecureTextFieldHotkeys.o +endif OBJS += VolumeHistory.o OBJS += Forms/AboutDialog.o OBJS += Forms/BenchmarkDialog.o