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:
@@ -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 $@
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user