summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/osx/salnsmenu.h6
-rw-r--r--vcl/osx/salframeview.mm32
-rw-r--r--vcl/osx/salmenu.cxx12
-rw-r--r--vcl/osx/salnsmenu.mm84
4 files changed, 116 insertions, 18 deletions
diff --git a/vcl/inc/osx/salnsmenu.h b/vcl/inc/osx/salnsmenu.h
index 9e0f9acf68ed..d6b065a7706e 100644
--- a/vcl/inc/osx/salnsmenu.h
+++ b/vcl/inc/osx/salnsmenu.h
@@ -44,15 +44,21 @@ class AquaSalMenuItem;
@interface SalNSMenuItem : NSMenuItem <NSMenuItemValidation>
{
AquaSalMenuItem* mpMenuItem;
+ BOOL mbReallyEnabled;
}
- (id)initWithMenuItem:(AquaSalMenuItem*)pMenuItem;
+- (BOOL)isReallyEnabled;
- (void)menuItemTriggered:(id)aSender;
- (BOOL)validateMenuItem:(NSMenuItem*)pMenuItem;
+- (void)setReallyEnabled:(BOOL)bEnabled;
@end
@interface SalNSMainMenu : NSMenu
{
+ NSEvent* mpLastPerformKeyEquivalentEvent;
}
+- (id)initWithTitle:(NSString*)pTitle;
+- (void)dealloc;
- (BOOL)performKeyEquivalent:(NSEvent*)pEvent;
@end
diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm
index eb8ed68add34..a8432aba31b9 100644
--- a/vcl/osx/salframeview.mm
+++ b/vcl/osx/salframeview.mm
@@ -1748,9 +1748,37 @@ static void updateWinDataInLiveResize(bool bInLiveResize)
-(void)noop: (id)aSender
{
(void)aSender;
- if( ! mbKeyHandled )
+ if( ! mbKeyHandled && mpLastEvent )
{
- if( ! [self sendSingleCharacter:mpLastEvent] )
+ // Related tdf#162843: replace the event's string parameter
+ // When using the Dvorak - QWERTY keyboard and the Command key
+ // is pressed, any key events that match a disabled menu item
+ // are handled here. However, the Dvorak - QWERTY event's
+ // charactersIgnoringModifiers string can cause cutting and
+ // copying to fail in the Find toolbar and the Find and Replace
+ // dialog so replace the event's charactersIgnoringModifiers
+ // string with the event's character string.
+ NSEvent* pEvent = mpLastEvent;
+ NSEventModifierFlags nModMask = [mpLastEvent modifierFlags];
+ if( nModMask & NSEventModifierFlagCommand )
+ {
+ switch( [mpLastEvent type] )
+ {
+ case NSEventTypeKeyDown:
+ case NSEventTypeKeyUp:
+ case NSEventTypeFlagsChanged:
+ {
+ NSString* pCharacters = [mpLastEvent characters];
+ NSString* pCharactersIgnoringModifiers = ( nModMask & NSEventModifierFlagShift ) ? [pCharacters uppercaseString] : pCharacters;
+ pEvent = [NSEvent keyEventWithType: [pEvent type] location: [pEvent locationInWindow] modifierFlags: nModMask timestamp: [pEvent timestamp] windowNumber: [pEvent windowNumber] context: nil characters: pCharacters charactersIgnoringModifiers: pCharactersIgnoringModifiers isARepeat: [pEvent isARepeat] keyCode: [pEvent keyCode]];
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if( ! [self sendSingleCharacter:pEvent] )
{
/* prevent recursion */
if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] )
diff --git a/vcl/osx/salmenu.cxx b/vcl/osx/salmenu.cxx
index dcac168f7e53..0410da4e99fd 100644
--- a/vcl/osx/salmenu.cxx
+++ b/vcl/osx/salmenu.cxx
@@ -412,7 +412,10 @@ void AquaSalMenu::enableMainMenu( bool bEnable )
for( int n = 1; n < nItems; n++ )
{
NSMenuItem* pItem = [pMainMenu itemAtIndex: n];
- [pItem setEnabled: bEnable ? YES : NO];
+ if( [pItem isKindOfClass: [SalNSMenuItem class]])
+ [static_cast<SalNSMenuItem*>(pItem) setReallyEnabled: bEnable];
+ else
+ [pItem setEnabled: bEnable];
}
}
}
@@ -581,7 +584,10 @@ void AquaSalMenu::EnableItem( unsigned nPos, bool bEnable )
if( nPos < maItems.size() )
{
NSMenuItem* pItem = maItems[nPos]->mpMenuItem;
- [pItem setEnabled: bEnable ? YES : NO];
+ if( [pItem isKindOfClass: [SalNSMenuItem class]])
+ [static_cast<SalNSMenuItem*>(pItem) setReallyEnabled: bEnable];
+ else
+ [pItem setEnabled: bEnable];
}
}
@@ -874,7 +880,7 @@ AquaSalMenuItem::AquaSalMenuItem( const SalItemParams* pItemData ) :
else
{
mpMenuItem = [[SalNSMenuItem alloc] initWithMenuItem: this];
- [mpMenuItem setEnabled: YES];
+ [static_cast<SalNSMenuItem*>(mpMenuItem) setReallyEnabled: YES];
// peel mnemonics because on mac there are no such things for menu items
// Delete CJK-style mnemonics for the dropdown menu of the 'New button' and lower menu of 'File > New'
diff --git a/vcl/osx/salnsmenu.mm b/vcl/osx/salnsmenu.mm
index 31a2ace83f07..383e0b574a54 100644
--- a/vcl/osx/salnsmenu.mm
+++ b/vcl/osx/salnsmenu.mm
@@ -142,8 +142,15 @@
action: @selector(menuItemTriggered:)
keyEquivalent: [NSString string]];
[ret setTarget: self];
+ mbReallyEnabled = [ret isEnabled];
return ret;
}
+
+-(BOOL)isReallyEnabled
+{
+ return mbReallyEnabled;
+}
+
-(void)menuItemTriggered: (id)aSender
{
(void)aSender;
@@ -187,8 +194,8 @@
[pCharacters isEqualToString: @"a"] ||
[pCharacters isEqualToString: @"z"] ) )
{
- NSEvent* pEvent = [NSApp currentEvent];
NSEvent* pKeyEvent = nil;
+ NSEvent* pEvent = [NSApp currentEvent];
if( pEvent )
{
switch( [pEvent type] )
@@ -196,23 +203,29 @@
case NSEventTypeKeyDown:
case NSEventTypeKeyUp:
case NSEventTypeFlagsChanged:
- pKeyEvent = pEvent;
+ // tdf#162843 replace the event's string parameters
+ // When using the Dvorak - QWERTY keyboard, the
+ // event's charactersIgnoringModifiers string causes
+ // pasting to fail so replace both the event's
+ // characters and charactersIgnoringModifiers strings
+ // with this menu item's key equivalent.
+ pKeyEvent = [NSEvent keyEventWithType: [pEvent type] location: [pEvent locationInWindow] modifierFlags: nModMask timestamp: [pEvent timestamp] windowNumber: [pEvent windowNumber] context: nil characters: pCharacters charactersIgnoringModifiers: pCharacters isARepeat: [pEvent isARepeat] keyCode: [pEvent keyCode]];
break;
default:
break;
}
+ }
- if( !pKeyEvent )
- {
- // Native key events appear to set the location to the
- // top left corner of the key window
- NSPoint aPoint = NSMakePoint(0, [pKeyWin frame].size.height);
- pKeyEvent = [NSEvent keyEventWithType: NSEventTypeKeyDown location: aPoint modifierFlags: nModMask timestamp: [[NSProcessInfo processInfo] systemUptime] windowNumber: [pKeyWin windowNumber] context: nil characters: pCharacters charactersIgnoringModifiers: pCharacters isARepeat: NO keyCode: 0];
- }
-
- [[pKeyWin contentView] keyDown: pKeyEvent];
- return;
+ if( !pKeyEvent )
+ {
+ // Native key events appear to set the location to the
+ // top left corner of the key window
+ NSPoint aPoint = NSMakePoint(0, [pKeyWin frame].size.height);
+ pKeyEvent = [NSEvent keyEventWithType: NSEventTypeKeyDown location: aPoint modifierFlags: nModMask timestamp: [[NSProcessInfo processInfo] systemUptime] windowNumber: [pKeyWin windowNumber] context: nil characters: pCharacters charactersIgnoringModifiers: pCharacters isARepeat: NO keyCode: 0];
}
+
+ [[pKeyWin contentView] keyDown: pKeyEvent];
+ return;
}
}
@@ -255,6 +268,12 @@
}
}
+-(void)setReallyEnabled: (BOOL)bEnabled
+{
+ mbReallyEnabled = bEnabled;
+ [self setEnabled: mbReallyEnabled];
+}
+
-(BOOL)validateMenuItem: (NSMenuItem *)pMenuItem
{
// Related: tdf#126638 disable all menu items when displaying modal windows
@@ -265,7 +284,18 @@
if (!pMenuItem || [NSApp modalWindow])
return NO;
- return [pMenuItem isEnabled];
+ // Related: tdf#126638 return the last enabled state set by the LibreOffice code
+ // Apparently whatever is returned will be passed to
+ // -[NSMenuItem setEnabled:] which can cause the enabled state
+ // to be different than the enabled state that the LibreOffice
+ // code expoects. This results in menu items failing to be
+ // reenabled after being temporarily disabled such as when a
+ // native modal dialog is closed. So, return the last enabled
+ // state set by the LibreOffice code.
+ if ([pMenuItem isKindOfClass: [SalNSMenuItem class]])
+ return [static_cast<SalNSMenuItem*>(pMenuItem) isReallyEnabled];
+ else
+ return [pMenuItem isEnabled];
}
@end
@@ -359,8 +389,36 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
@implementation SalNSMainMenu
+- (id)initWithTitle:(NSString*)pTitle
+{
+ mpLastPerformKeyEquivalentEvent = nil;
+ return [super initWithTitle:pTitle];
+}
+
+- (void)dealloc
+{
+ if (mpLastPerformKeyEquivalentEvent)
+ [mpLastPerformKeyEquivalentEvent release];
+
+ [super dealloc];
+}
+
- (BOOL)performKeyEquivalent:(NSEvent*)pEvent
{
+ // Related: tdf#162843 prevent dispatch of the same event more than once
+ // When pressing Command-V with a Dvorak - QWERTY keyboard,
+ // that single event passes through this selector twice which
+ // causes content to be pasted twice in any text fields in the
+ // Find and Replace dialog.
+ if (pEvent == mpLastPerformKeyEquivalentEvent)
+ return false;
+
+ if (mpLastPerformKeyEquivalentEvent)
+ [mpLastPerformKeyEquivalentEvent release];
+ mpLastPerformKeyEquivalentEvent = pEvent;
+ if (mpLastPerformKeyEquivalentEvent)
+ [mpLastPerformKeyEquivalentEvent retain];
+
bool bRet = [super performKeyEquivalent: pEvent];
// tdf#126638 dispatch key shortcut events to modal windows