macosx: split hotkeys handling to a designated class

This commit is contained in:
Felix Paul Kühne 2019-04-15 18:58:07 +02:00
parent 7d6595196a
commit 5f566bd811
8 changed files with 331 additions and 45 deletions

View File

@ -99,6 +99,7 @@
6BBBF9851F7B257100B404CD /* VLCLogMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BBBF9841F7B257100B404CD /* VLCLogMessage.m */; };
6BF093F91EE0182B0049D8B0 /* VLCTimeField.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF093F81EE0182B0049D8B0 /* VLCTimeField.m */; };
6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */; };
7D0F5A9B2264EB410009C48A /* VLCHotkeysController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F5A9A2264EB410009C48A /* VLCHotkeysController.m */; };
7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */; };
7D0F64062202047900FDB91F /* VLCLibraryCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F64042202047900FDB91F /* VLCLibraryCollectionViewItem.m */; };
7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */; };
@ -416,6 +417,8 @@
6BF5C5021EFE66EF008A9C12 /* VLCHUDTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCHUDTableView.h; sourceTree = "<group>"; };
6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCHUDTableView.m; sourceTree = "<group>"; };
7D0A387820CBCC4D00D4BF3B /* videotoolbox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = videotoolbox.m; path = ../../../modules/codec/videotoolbox.m; sourceTree = "<group>"; };
7D0F5A992264EB410009C48A /* VLCHotkeysController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCHotkeysController.h; sourceTree = "<group>"; };
7D0F5A9A2264EB410009C48A /* VLCHotkeysController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCHotkeysController.m; sourceTree = "<group>"; };
7D0F63FD2201F63400FDB91F /* VLCPlaylistTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistTableCellView.h; sourceTree = "<group>"; };
7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistTableCellView.m; sourceTree = "<group>"; };
7D0F64002201F66D00FDB91F /* VLCPlaylistTableCellView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VLCPlaylistTableCellView.xib; sourceTree = "<group>"; };
@ -803,6 +806,8 @@
children = (
7D66D4372200C5B80040D04A /* VLCVideoFilterHelper.h */,
7D66D4382200C5B80040D04A /* VLCVideoFilterHelper.m */,
7D0F5A992264EB410009C48A /* VLCHotkeysController.h */,
7D0F5A9A2264EB410009C48A /* VLCHotkeysController.m */,
);
path = coreinteraction;
sourceTree = "<group>";
@ -1580,6 +1585,7 @@
7D2E0EDB20CD204D0033A221 /* VLCWindow.m in Sources */,
6B4D50A71E7AB52C004479B5 /* NSScreen+VLCAdditions.m in Sources */,
1C3113DD1E508C6900D4DD76 /* VLCTrackSynchronizationWindowController.m in Sources */,
7D0F5A9B2264EB410009C48A /* VLCHotkeysController.m in Sources */,
6B6FFF701EF9EC350001CEB1 /* CompatibilityFixes.m in Sources */,
1C3113DF1E508C6900D4DD76 /* VLCVideoEffectsWindowController.m in Sources */,
1C3113E11E508C6900D4DD76 /* VLCVoutView.m in Sources */,

View File

@ -26,6 +26,8 @@ libmacosx_plugin_la_LDFLAGS += -Wl,-framework,Sparkle
endif
libmacosx_plugin_la_SOURCES = \
gui/macosx/coreinteraction/VLCHotkeysController.h \
gui/macosx/coreinteraction/VLCHotkeysController.m \
gui/macosx/coreinteraction/VLCVideoFilterHelper.h \
gui/macosx/coreinteraction/VLCVideoFilterHelper.m \
gui/macosx/extensions/NSScreen+VLCAdditions.h \

View File

@ -0,0 +1,38 @@
/*****************************************************************************
* VLCHotkeysController.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2002-2019 VLC authors and VideoLAN
*
* Authors: Felix Paul Kühne <fkuehne # videolan dot org>
* David Fuhrmann <dfuhrmann # videolan dot org>
* Derk-Jan Hartman <hartman # videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <vlc_vout.h>
NS_ASSUME_NONNULL_BEGIN
@interface VLCHotkeysController : NSObject
- (BOOL)handleVideoOutputKeyDown:(id)anEvent forVideoOutput:(vout_thread_t *)p_vout;
- (BOOL)performKeyEquivalent:(NSEvent *)anEvent;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,267 @@
/*****************************************************************************
* VLCHotkeysController.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2003-2019 VLC authors and VideoLAN
*
* Authors: Felix Paul Kühne <fkuehne # videolan dot org>
* David Fuhrmann <dfuhrmann # videolan dot org>
* Derk-Jan Hartman <hartman # videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCHotkeysController.h"
#import "main/VLCMain.h"
#import "playlist/VLCPlaylistController.h"
#import "playlist/VLCPlayerController.h"
#import <vlc_actions.h>
#import <vlc_plugin.h>
#import <vlc_modules.h>
@interface VLCHotkeysController()
{
NSArray *_usedHotkeys;
}
@end
@implementation VLCHotkeysController
- (instancetype)init
{
self = [super init];
if (self) {
[self updateCurrentlyUsedHotkeys];
}
return self;
}
- (void)updateCurrentlyUsedHotkeys
{
NSMutableArray *mutArray = [[NSMutableArray alloc] init];
/* Get the main Module */
module_t *p_main = module_get_main();
assert(p_main);
unsigned confsize;
module_config_t *p_config;
p_config = module_config_get(p_main, &confsize);
for (size_t i = 0; i < confsize; i++) {
module_config_t *p_item = p_config + i;
if (CONFIG_ITEM(p_item->i_type) && p_item->psz_name != NULL
&& !strncmp(p_item->psz_name , "key-", 4)
&& !EMPTY_STR(p_item->psz_text)) {
if (p_item->value.psz)
[mutArray addObject:toNSStr(p_item->value.psz)];
}
}
module_config_free(p_config);
_usedHotkeys = [[NSArray alloc] initWithArray:mutArray copyItems:YES];
}
- (BOOL)handleVideoOutputKeyDown:(id)anEvent forVideoOutput:(vout_thread_t *)p_vout
{
VLCPlayerController *playerController = [[[VLCMain sharedInstance] playlistController] playerController];
unichar key = 0;
vlc_value_t val;
unsigned int i_pressed_modifiers = 0;
val.i_int = 0;
i_pressed_modifiers = [anEvent modifierFlags];
if (i_pressed_modifiers & NSShiftKeyMask)
val.i_int |= KEY_MODIFIER_SHIFT;
if (i_pressed_modifiers & NSControlKeyMask)
val.i_int |= KEY_MODIFIER_CTRL;
if (i_pressed_modifiers & NSAlternateKeyMask)
val.i_int |= KEY_MODIFIER_ALT;
if (i_pressed_modifiers & NSCommandKeyMask)
val.i_int |= KEY_MODIFIER_COMMAND;
NSString *characters = [anEvent charactersIgnoringModifiers];
if ([characters length] > 0) {
key = [[characters lowercaseString] characterAtIndex: 0];
if (key) {
/* Escape should always get you out of fullscreen */
if (key == (unichar) 0x1b) {
if (playerController.fullscreen) {
[playerController toggleFullscreen];
}
}
/* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
else if (key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask) {
[playerController toggleFullscreen];
} else if (p_vout) {
val.i_int |= (int)CocoaKeyToVLC(key);
var_Set(vlc_object_instance(p_vout), "key-pressed", val);
}
else
msg_Dbg(getIntf(), "could not send keyevent to VLC core");
return YES;
}
}
return NO;
}
- (BOOL)performKeyEquivalent:(NSEvent *)anEvent
{
BOOL enforced = NO;
// these are key events which should be handled by vlc core, but are attached to a main menu item
if (![self isEvent:anEvent forKey:"key-vol-up"] &&
![self isEvent:anEvent forKey:"key-vol-down"] &&
![self isEvent:anEvent forKey:"key-vol-mute"] &&
![self isEvent:anEvent forKey:"key-prev"] &&
![self isEvent:anEvent forKey:"key-next"] &&
![self isEvent:anEvent forKey:"key-jump+short"] &&
![self isEvent:anEvent forKey:"key-jump-short"]) {
/* We indeed want to prioritize some Cocoa key equivalent against libvlc,
so we perform the menu equivalent now. */
if ([[NSApp mainMenu] performKeyEquivalent:anEvent]) {
return TRUE;
}
} else {
enforced = YES;
}
return [self hasDefinedShortcutKey:anEvent force:enforced] || [self keyEvent:anEvent];
}
- (BOOL)isEvent:(NSEvent *)anEvent forKey:(const char *)keyString
{
char *key = config_GetPsz(keyString);
unsigned int keyModifiers = VLCModifiersToCocoa(key);
NSString *vlcKeyString = VLCKeyToString(key);
FREENULL(key);
NSString *characters = [anEvent charactersIgnoringModifiers];
if ([characters length] > 0) {
return [[characters lowercaseString] isEqualToString: vlcKeyString] &&
(keyModifiers & NSShiftKeyMask) == ([anEvent modifierFlags] & NSShiftKeyMask) &&
(keyModifiers & NSControlKeyMask) == ([anEvent modifierFlags] & NSControlKeyMask) &&
(keyModifiers & NSAlternateKeyMask) == ([anEvent modifierFlags] & NSAlternateKeyMask) &&
(keyModifiers & NSCommandKeyMask) == ([anEvent modifierFlags] & NSCommandKeyMask);
}
return NO;
}
- (BOOL)keyEvent:(NSEvent *)anEvent
{
BOOL eventHandled = NO;
NSString * characters = [anEvent charactersIgnoringModifiers];
if ([characters length] > 0) {
unichar key = [characters characterAtIndex: 0];
if (key) {
VLCPlayerController *playerController = [[[VLCMain sharedInstance] playlistController] playerController];
vout_thread_t *p_vout = [playerController mainVideoOutputThread];
if (p_vout != NULL) {
/* Escape */
if (key == (unichar) 0x1b) {
if (var_GetBool(p_vout, "fullscreen")) {
[playerController toggleFullscreen];
eventHandled = YES;
}
}
vout_Release(p_vout);
}
}
}
return eventHandled;
}
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)enforced
{
intf_thread_t *p_intf = getIntf();
if (!p_intf)
return NO;
unichar key = 0;
vlc_value_t val;
unsigned int i_pressed_modifiers = 0;
val.i_int = 0;
i_pressed_modifiers = [o_event modifierFlags];
if (i_pressed_modifiers & NSControlKeyMask)
val.i_int |= KEY_MODIFIER_CTRL;
if (i_pressed_modifiers & NSAlternateKeyMask)
val.i_int |= KEY_MODIFIER_ALT;
if (i_pressed_modifiers & NSShiftKeyMask)
val.i_int |= KEY_MODIFIER_SHIFT;
if (i_pressed_modifiers & NSCommandKeyMask)
val.i_int |= KEY_MODIFIER_COMMAND;
NSString * characters = [o_event charactersIgnoringModifiers];
if ([characters length] > 0) {
key = [[characters lowercaseString] characterAtIndex: 0];
/* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
if (key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask) {
[[[[VLCMain sharedInstance] playlistController] playerController] toggleFullscreen];
return YES;
}
if (!enforced) {
switch(key) {
case NSDeleteCharacter:
case NSDeleteFunctionKey:
case NSDeleteCharFunctionKey:
case NSBackspaceCharacter:
case NSUpArrowFunctionKey:
case NSDownArrowFunctionKey:
case NSEnterCharacter:
case NSCarriageReturnCharacter:
return NO;
}
}
val.i_int |= CocoaKeyToVLC(key);
BOOL b_found_key = NO;
NSUInteger numberOfUsedHotkeys = [_usedHotkeys count];
for (NSUInteger i = 0; i < numberOfUsedHotkeys; i++) {
const char *str = [[_usedHotkeys objectAtIndex:i] UTF8String];
unsigned int i_keyModifiers = VLCModifiersToCocoa((char *)str);
if ([[characters lowercaseString] isEqualToString:VLCKeyToString((char *)str)] &&
(i_keyModifiers & NSShiftKeyMask) == (i_pressed_modifiers & NSShiftKeyMask) &&
(i_keyModifiers & NSControlKeyMask) == (i_pressed_modifiers & NSControlKeyMask) &&
(i_keyModifiers & NSAlternateKeyMask) == (i_pressed_modifiers & NSAlternateKeyMask) &&
(i_keyModifiers & NSCommandKeyMask) == (i_pressed_modifiers & NSCommandKeyMask)) {
b_found_key = YES;
break;
}
}
if (b_found_key) {
var_SetInteger(vlc_object_instance(p_intf), "key-pressed", val.i_int);
return YES;
}
}
return NO;
}
@end

View File

@ -75,6 +75,7 @@ static NSString * VLCAppleRemoteSettingChangedNotification = @"VLCAppleRemoteSet
@class VLCExtensionsManager;
@class VLCStatusBarIcon;
@class VLCPlaylistController;
@class VLCHotkeysController;
@interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
@ -83,6 +84,7 @@ static NSString * VLCAppleRemoteSettingChangedNotification = @"VLCAppleRemoteSet
@property (nonatomic, readwrite) BOOL playlistUpdatedSelectorInQueue;
@property (readonly) VLCLibraryWindowController *libraryWindowController;
@property (readonly) VLCPlaylistController *playlistController;
@property (readonly) VLCHotkeysController *hotkeysController;
+ (VLCMain *)sharedInstance;
+ (void)killInstance;

View File

@ -42,6 +42,8 @@
#include <vlc_url.h>
#include <vlc_variables.h>
#import "coreinteraction/VLCHotkeysController.h"
#import "library/VLCLibraryWindow.h"
#import "main/CompatibilityFixes.h"
@ -240,6 +242,8 @@ static VLCMain *sharedInstance = nil;
[VLCApplication sharedApplication].delegate = self;
_hotkeysController = [[VLCHotkeysController alloc] init];
_playlistController = [[VLCPlaylistController alloc] initWithPlaylist:vlc_intf_GetMainPlaylist(p_intf)];
_continuityController = [[VLCPlaybackContinuityController alloc] init];

View File

@ -33,14 +33,15 @@
#import <QuartzCore/QuartzCore.h>
#import <vlc_actions.h>
#import "coreinteraction/VLCHotkeysController.h"
#import "main/VLCMain.h"
#import "menus/VLCMainMenu.h"
#import "playlist/VLCPlaylistController.h"
#import "playlist/VLCPlayerController.h"
#import "windows/video/VLCVideoWindowCommon.h"
#import <vlc_actions.h>
/*****************************************************************************
* VLCVoutView implementation
*****************************************************************************/
@ -56,6 +57,7 @@
vout_thread_t *p_vout;
VLCPlayerController *_playerController;
VLCHotkeysController *_hotkeysController;
}
@end
@ -78,7 +80,9 @@
[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
i_lastScrollWheelDirection = 0;
f_cumulated_magnification = 0.0;
_playerController = [[[VLCMain sharedInstance] playlistController] playerController];
VLCMain *mainInstance = [VLCMain sharedInstance];
_playerController = [[mainInstance playlistController] playerController];
_hotkeysController = [mainInstance hotkeysController];
}
return self;
@ -149,53 +153,14 @@
- (void)keyDown:(NSEvent *)o_event
{
unichar key = 0;
vlc_value_t val;
unsigned int i_pressed_modifiers = 0;
val.i_int = 0;
i_pressed_modifiers = [o_event modifierFlags];
if (i_pressed_modifiers & NSShiftKeyMask)
val.i_int |= KEY_MODIFIER_SHIFT;
if (i_pressed_modifiers & NSControlKeyMask)
val.i_int |= KEY_MODIFIER_CTRL;
if (i_pressed_modifiers & NSAlternateKeyMask)
val.i_int |= KEY_MODIFIER_ALT;
if (i_pressed_modifiers & NSCommandKeyMask)
val.i_int |= KEY_MODIFIER_COMMAND;
NSString * characters = [o_event charactersIgnoringModifiers];
if ([characters length] > 0) {
key = [[characters lowercaseString] characterAtIndex: 0];
if (key) {
/* Escape should always get you out of fullscreen */
if (key == (unichar) 0x1b) {
if (_playerController.fullscreen) {
[_playerController toggleFullscreen];
}
}
/* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
else if (key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask) {
[_playerController toggleFullscreen];
} else if (p_vout) {
val.i_int |= (int)CocoaKeyToVLC(key);
var_Set(vlc_object_instance(p_vout), "key-pressed", val);
}
else
msg_Dbg(getIntf(), "could not send keyevent to VLC core");
return;
}
if (![_hotkeysController handleVideoOutputKeyDown:o_event forVideoOutput:p_vout]) {
[super keyDown: o_event];
}
[super keyDown: o_event];
}
- (BOOL)performKeyEquivalent:(NSEvent *)o_event
{
// FIXME: this hack is gross and wrong on many levels
return NO; //[[[VLCMain sharedInstance] mainWindow] performKeyEquivalent: o_event];
return [_hotkeysController performKeyEquivalent:o_event];
}
- (void)mouseDown:(NSEvent *)o_event

View File

@ -448,6 +448,8 @@ modules/demux/xa.c
modules/demux/xiph.h
modules/demux/xiph_metadata.c
modules/demux/xiph_metadata.h
modules/gui/macosx/coreinteraction/VLCHotkeysController.h
modules/gui/macosx/coreinteraction/VLCHotkeysController.m
modules/gui/macosx/coreinteraction/VLCVideoFilterHelper.h
modules/gui/macosx/coreinteraction/VLCVideoFilterHelper.m
modules/gui/macosx/extensions/NSScreen+VLCAdditions.h