1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-17 01:56:10 -05:00

macOS: Fix Command-A in password fields

Install a macOS-specific secure text field hotkey handler so Command-A selects the full contents of password controls when Cocoa does not route the shortcut through wxWidgets accelerators. Keep the existing wxWidgets accelerator handler for Command-V and Command-A, and recognize the standard paste/select-all IDs when they do reach the C++ event path.

Add Objective-C++ compilation support for the macOS helper and include it in the GUI target only on macOS.

Fixes https://github.com/veracrypt/VeraCrypt/issues/1567
This commit is contained in:
Mounir IDRASSI
2026-05-28 15:33:18 +02:00
parent cfd54af700
commit 0caacd3405
5 changed files with 156 additions and 5 deletions
+7 -1
View File
@@ -51,7 +51,13 @@ clean:
%.o: %.cpp
@echo Compiling $(<F)
$(CXX) $(CXXFLAGS) -c $< -o $@
ifeq "$(PLATFORM)" "MacOSX"
%.o: %.mm
@echo Compiling $(<F)
$(CXX) $(CXXFLAGS) -x objective-c++ -fblocks -c $< -o $@
endif
%.osse41: %.cpp
@echo Compiling $(<F)
$(CXX) $(CXXFLAGS) -mssse3 -msse4.1 -c $< -o $@
+12 -4
View File
@@ -28,6 +28,9 @@
#include "Application.h"
#include "GraphicUserInterface.h"
#include "FatalErrorHandler.h"
#ifdef TC_MACOSX
#include "MacOSXSecureTextFieldHotkeys.h"
#endif
#include "Forms/DeviceSelectionDialog.h"
#include "Forms/KeyfileGeneratorDialog.h"
#include "Forms/MainFrame.h"
@@ -97,6 +100,7 @@ namespace VeraCrypt
#ifdef TC_MACOSX
g_customIdCmdV = wxNewId();
g_customIdCmdA = wxNewId();
InstallMacOSXSecureTextFieldHotkeys();
wxApp::s_macHelpMenuTitleName = LangString["MENU_HELP"];
#endif
#if wxCHECK_VERSION(3, 1, 6)
@@ -106,6 +110,9 @@ namespace VeraCrypt
GraphicUserInterface::~GraphicUserInterface ()
{
#ifdef TC_MACOSX
UninstallMacOSXSecureTextFieldHotkeys();
#endif
try
{
if (RandomNumberGenerator::IsRunning())
@@ -741,8 +748,9 @@ namespace VeraCrypt
bool GraphicUserInterface::HandlePasswordEntryCustomEvent (wxEvent& event)
{
bool bHandled = false;
if ( (event.GetEventType() == wxEVT_MENU)
&& ((event.GetId() == g_customIdCmdV) || (event.GetId() == g_customIdCmdA)))
const bool isPasteShortcut = (event.GetId() == g_customIdCmdV) || (event.GetId() == wxID_PASTE);
const bool isSelectAllShortcut = (event.GetId() == g_customIdCmdA) || (event.GetId() == wxID_SELECTALL);
if ((event.GetEventType() == wxEVT_MENU) && (isPasteShortcut || isSelectAllShortcut))
{
wxWindow* focusedCtrl = wxWindow::FindFocus();
if (focusedCtrl
@@ -750,9 +758,9 @@ namespace VeraCrypt
&& (focusedCtrl->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;
}
+20
View File
@@ -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
+114
View File
@@ -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 <Cocoa/Cocoa.h>
#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 <wxTextCtrl *> (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
+3
View File
@@ -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