Merge branch 'feat-macos-sec-kbd' of https://github.com/page-down/kitty

This commit is contained in:
Kovid Goyal 2022-01-09 22:03:31 +05:30
commit eafd20b4b3
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
12 changed files with 232 additions and 194 deletions

View File

@ -607,135 +607,6 @@ translateKeyToModifierFlag(uint32_t key)
static const NSRange kEmptyRange = { NSNotFound, 0 };
// SecureKeyboardEntryController {{{
@interface SecureKeyboardEntryController : NSObject
@property (nonatomic, readonly) BOOL isDesired;
@property (nonatomic, readonly, getter=isEnabled) BOOL enabled;
+ (instancetype)sharedInstance;
- (void)toggle;
- (void)update;
@end
@implementation SecureKeyboardEntryController {
int _count;
BOOL _desired;
}
+ (instancetype)sharedInstance {
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (instancetype)init {
self = [super init];
if (self) {
_desired = false;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidResignActive:)
name:NSApplicationDidResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:NSApplicationDidBecomeActiveNotification
object:nil];
if ([NSApp isActive]) {
[self update];
}
}
return self;
}
#pragma mark - API
- (void)toggle {
// Set _desired to the opposite of the current state.
_desired = !_desired;
debug_key("toggle called. Setting desired to %d", _desired);
// Try to set the system's state of secure input to the desired state.
[self update];
}
- (BOOL)isEnabled {
return !!IsSecureEventInputEnabled();
}
- (BOOL)isDesired {
return _desired;
}
#pragma mark - Notifications
- (void)applicationDidResignActive:(NSNotification *)notification {
(void)notification;
if (_count > 0) {
debug_key("Application resigning active.");
[self update];
}
}
- (void)applicationDidBecomeActive:(NSNotification *)notification {
(void)notification;
if (self.isDesired) {
debug_key("Application became active.");
[self update];
}
}
#pragma mark - Private
- (BOOL)allowed {
return [NSApp isActive];
}
- (void)update {
debug_key("Update secure keyboard entry. desired=%d active=%d\n",
(int)self.isDesired, (int)[NSApp isActive]);
const BOOL secure = self.isDesired && [self allowed];
if (secure && _count > 0) {
debug_key("Want to turn on secure input but it's already on\n");
return;
}
if (!secure && _count == 0) {
debug_key("Want to turn off secure input but it's already off\n");
return;
}
debug_key("Before: IsSecureEventInputEnabled returns %d ", (int)self.isEnabled);
if (secure) {
OSErr err = EnableSecureEventInput();
debug_key("EnableSecureEventInput err=%d ", (int)err);
if (err) {
debug_key("EnableSecureEventInput failed with error %d ", (int)err);
} else {
_count += 1;
}
} else {
OSErr err = DisableSecureEventInput();
debug_key("DisableSecureEventInput err=%d ", (int)err);
if (err) {
debug_key("DisableSecureEventInput failed with error %d ", (int)err);
} else {
_count -= 1;
}
}
debug_key("After: IsSecureEventInputEnabled returns %d\n", (int)self.isEnabled);
}
@end
// }}}
// Delegate for window related notifications {{{
@interface GLFWWindowDelegate : NSObject
@ -1586,8 +1457,6 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
if (self != nil) {
glfw_window = initWindow;
self.tabbingMode = NSWindowTabbingModeDisallowed;
SecureKeyboardEntryController *k = [SecureKeyboardEntryController sharedInstance];
if (!k.isDesired && [[NSUserDefaults standardUserDefaults] boolForKey:@"SecureKeyboardEntry"]) [k toggle];
}
return self;
}
@ -1599,10 +1468,6 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
- (BOOL)validateMenuItem:(NSMenuItem *)item {
if (item.action == @selector(performMiniaturize:)) return YES;
if (item.action == @selector(toggleSecureInput:)) {
item.state = [SecureKeyboardEntryController sharedInstance].isDesired ? NSControlStateValueOn : NSControlStateValueOff;
return YES;
}
return [super validateMenuItem:item];
}
@ -1612,13 +1477,6 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
else [super performMiniaturize:sender];
}
- (void)toggleSecureInput:(id)sender {
(void)sender;
SecureKeyboardEntryController *k = [SecureKeyboardEntryController sharedInstance];
[k toggle];
[[NSUserDefaults standardUserDefaults] setBool:k.isDesired forKey:@"SecureKeyboardEntry"];
}
- (BOOL)canBecomeKeyWindow
{
// Required for NSWindowStyleMaskBorderless windows

View File

@ -39,7 +39,7 @@ from .fast_data_types import (
set_application_quit_request, set_background_image, set_boss,
set_clipboard_string, set_in_sequence_mode, set_options,
set_os_window_size, set_os_window_title, thread_write, toggle_fullscreen,
toggle_maximized
toggle_maximized, toggle_secure_input
)
from .key_encoding import get_name_to_functional_number_map
from .keys import get_shortcut, shortcut_matches
@ -721,6 +721,10 @@ class Boss:
def toggle_maximized(self, os_window_id: int = 0) -> None:
toggle_maximized(os_window_id)
@ac('misc', 'Toggle macOS secure keyboard entry')
def toggle_macos_secure_keyboard_entry(self) -> None:
toggle_secure_input()
def start(self, first_os_window_id: int) -> None:
if not getattr(self, 'io_thread_started', False):
self.child_monitor.start()
@ -1890,7 +1894,7 @@ class Boss:
from .fonts.box_drawing import set_scale
# Update options storage
set_options(opts, is_wayland(), self.args.debug_rendering, self.args.debug_font_fallback)
set_options(opts, is_wayland(), self.args.debug_keyboard, self.args.debug_rendering, self.args.debug_font_fallback)
apply_options_update()
set_layout_options(opts)
set_default_env(opts.env.copy())

View File

@ -1039,6 +1039,7 @@ process_cocoa_pending_actions(void) {
if (cocoa_pending_actions[CLOSE_WINDOW]) { call_boss(close_window, NULL); }
if (cocoa_pending_actions[RESET_TERMINAL]) { call_boss(clear_terminal, "sO", "reset", Py_True ); }
if (cocoa_pending_actions[RELOAD_CONFIG]) { call_boss(load_config_file, NULL); }
if (cocoa_pending_actions[TOGGLE_MACOS_SECURE_KEYBOARD_ENTRY]) { call_boss(toggle_macos_secure_keyboard_entry, NULL); }
if (cocoa_pending_actions_data.wd) {
if (cocoa_pending_actions[NEW_OS_WINDOW_WITH_WD]) { call_boss(new_os_window_with_wd, "s", cocoa_pending_actions_data.wd); }
if (cocoa_pending_actions[NEW_TAB_WITH_WD]) { call_boss(new_tab_with_wd, "s", cocoa_pending_actions_data.wd); }

View File

@ -9,6 +9,7 @@
#include "state.h"
#include "cleanup.h"
#include "monotonic.h"
#include <Carbon/Carbon.h>
#include <Cocoa/Cocoa.h>
#ifndef KITTY_USE_DEPRECATED_MACOS_NOTIFICATION_API
#include <UserNotifications/UserNotifications.h>
@ -75,6 +76,137 @@ find_app_name(void) {
return @"kitty";
}
#define debug_key(...) if (global_state.debug_keyboard) { fprintf(stderr, __VA_ARGS__); fflush(stderr); }
// SecureKeyboardEntryController {{{
@interface SecureKeyboardEntryController : NSObject
@property (nonatomic, readonly) BOOL isDesired;
@property (nonatomic, readonly, getter=isEnabled) BOOL enabled;
+ (instancetype)sharedInstance;
- (void)toggle;
- (void)update;
@end
@implementation SecureKeyboardEntryController {
int _count;
BOOL _desired;
}
+ (instancetype)sharedInstance {
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (instancetype)init {
self = [super init];
if (self) {
_desired = false;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidResignActive:)
name:NSApplicationDidResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:NSApplicationDidBecomeActiveNotification
object:nil];
if ([NSApp isActive]) {
[self update];
}
}
return self;
}
#pragma mark - API
- (void)toggle {
// Set _desired to the opposite of the current state.
_desired = !_desired;
debug_key("SecureKeyboardEntry: toggle called. Setting desired to %d ", _desired);
// Try to set the system's state of secure input to the desired state.
[self update];
}
- (BOOL)isEnabled {
return !!IsSecureEventInputEnabled();
}
- (BOOL)isDesired {
return _desired;
}
#pragma mark - Notifications
- (void)applicationDidResignActive:(NSNotification *)notification {
(void)notification;
if (_count > 0) {
debug_key("SecureKeyboardEntry: Application resigning active.");
[self update];
}
}
- (void)applicationDidBecomeActive:(NSNotification *)notification {
(void)notification;
if (self.isDesired) {
debug_key("SecureKeyboardEntry: Application became active.");
[self update];
}
}
#pragma mark - Private
- (BOOL)allowed {
return [NSApp isActive];
}
- (void)update {
debug_key("Update secure keyboard entry. desired=%d active=%d\n",
(int)self.isDesired, (int)[NSApp isActive]);
const BOOL secure = self.isDesired && [self allowed];
if (secure && _count > 0) {
debug_key("Want to turn on secure input but it's already on\n");
return;
}
if (!secure && _count == 0) {
debug_key("Want to turn off secure input but it's already off\n");
return;
}
debug_key("Before: IsSecureEventInputEnabled returns %d ", (int)self.isEnabled);
if (secure) {
OSErr err = EnableSecureEventInput();
debug_key("EnableSecureEventInput err=%d ", (int)err);
if (err) {
debug_key("EnableSecureEventInput failed with error %d ", (int)err);
} else {
_count += 1;
}
} else {
OSErr err = DisableSecureEventInput();
debug_key("DisableSecureEventInput err=%d ", (int)err);
if (err) {
debug_key("DisableSecureEventInput failed with error %d ", (int)err);
} else {
_count -= 1;
}
}
debug_key("After: IsSecureEventInputEnabled returns %d\n", (int)self.isEnabled);
}
@end
// }}}
@interface GlobalMenuTarget : NSObject
+ (GlobalMenuTarget *) shared_instance;
@end
@ -95,12 +227,20 @@ PENDING(new_window, NEW_WINDOW)
PENDING(close_window, CLOSE_WINDOW)
PENDING(reset_terminal, RESET_TERMINAL)
PENDING(reload_config, RELOAD_CONFIG)
PENDING(toggle_macos_secure_keyboard_entry, TOGGLE_MACOS_SECURE_KEYBOARD_ENTRY)
- (void)open_kitty_website_url:(id)sender {
(void)sender;
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://sw.kovidgoyal.net/kitty/"]];
}
- (BOOL)validateMenuItem:(NSMenuItem *)item {
if (item.action == @selector(toggle_macos_secure_keyboard_entry:)) {
item.state = [SecureKeyboardEntryController sharedInstance].isDesired ? NSControlStateValueOn : NSControlStateValueOff;
}
return YES;
}
#undef PENDING
+ (GlobalMenuTarget *) shared_instance
@ -108,8 +248,11 @@ PENDING(reload_config, RELOAD_CONFIG)
static GlobalMenuTarget *sharedGlobalMenuTarget = nil;
@synchronized(self)
{
if (!sharedGlobalMenuTarget)
if (!sharedGlobalMenuTarget) {
sharedGlobalMenuTarget = [[GlobalMenuTarget alloc] init];
SecureKeyboardEntryController *k = [SecureKeyboardEntryController sharedInstance];
if (!k.isDesired && [[NSUserDefaults standardUserDefaults] boolForKey:@"SecureKeyboardEntry"]) [k toggle];
}
return sharedGlobalMenuTarget;
}
}
@ -123,6 +266,7 @@ typedef struct {
typedef struct {
GlobalShortcut new_os_window, close_os_window, close_tab, edit_config_file, reload_config;
GlobalShortcut previous_tab, next_tab, new_tab, new_window, close_window, reset_terminal;
GlobalShortcut toggle_macos_secure_keyboard_entry;
} GlobalShortcuts;
static GlobalShortcuts global_shortcuts;
@ -137,6 +281,7 @@ cocoa_set_global_shortcut(PyObject *self UNUSED, PyObject *args) {
Q(new_os_window); else Q(close_os_window); else Q(close_tab); else Q(edit_config_file);
else Q(new_tab); else Q(next_tab); else Q(previous_tab);
else Q(new_window); else Q(close_window); else Q(reset_terminal); else Q(reload_config);
else Q(toggle_macos_secure_keyboard_entry);
#undef Q
if (gs == NULL) { PyErr_SetString(PyExc_KeyError, "Unknown shortcut name"); return NULL; }
int cocoa_mods;
@ -419,10 +564,7 @@ cocoa_create_global_menu(void) {
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
[[appMenu addItemWithTitle:@"Secure Keyboard Entry"
action:@selector(toggleSecureInput:)
keyEquivalent:@"s"]
setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
MENU_ITEM(appMenu, @"Secure Keyboard Entry", toggle_macos_secure_keyboard_entry);
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", app_name]
@ -547,6 +689,13 @@ cocoa_alt_option_key_pressed(NSUInteger flags) {
return (q & flags) == q;
}
void
cocoa_toggle_secure_keyboard_entry(void) {
SecureKeyboardEntryController *k = [SecureKeyboardEntryController sharedInstance];
[k toggle];
[[NSUserDefaults standardUserDefaults] setBool:k.isDesired forKey:@"SecureKeyboardEntry"];
}
void
cocoa_focus_window(void *w) {
NSWindow *window = (NSWindow*)w;

View File

@ -526,6 +526,7 @@ def sync_os_window_title(os_window_id: int) -> None:
def set_options(
opts: Optional[Options],
is_wayland: bool = False,
debug_keyboard: bool = False,
debug_rendering: bool = False,
debug_font_fallback: bool = False
) -> None:
@ -763,6 +764,8 @@ def get_clipboard_string() -> str:
def focus_os_window(os_window_id: int, also_raise: bool = True) -> bool:
pass
def toggle_secure_input() -> None:
pass
def start_profiler(path: str) -> None:
pass

View File

@ -24,6 +24,7 @@ extern void cocoa_set_activation_policy(bool);
extern void cocoa_set_titlebar_appearance(void *w, unsigned int theme);
extern void cocoa_set_titlebar_color(void *w, color_type color);
extern bool cocoa_alt_option_key_pressed(unsigned long);
extern void cocoa_toggle_secure_keyboard_entry(void);
extern size_t cocoa_get_workspace_ids(void *w, size_t *workspace_ids, size_t array_sz);
extern monotonic_t cocoa_cursor_blink_interval(void);
@ -965,6 +966,13 @@ focus_os_window(OSWindow *w, bool also_raise) {
}
}
void
toggle_secure_input(void) {
#ifdef __APPLE__
cocoa_toggle_secure_keyboard_entry();
#endif
}
// Global functions {{{
static void
error_callback(int error, const char* description) {

View File

@ -151,7 +151,7 @@ def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ())
func_map[parts].append(k)
for ac in ('new_os_window', 'close_os_window', 'close_tab', 'edit_config_file', 'previous_tab',
'next_tab', 'new_tab', 'new_window', 'close_window'):
'next_tab', 'new_tab', 'new_window', 'close_window', 'toggle_macos_secure_keyboard_entry'):
val = get_macos_shortcut_for(func_map, ac)
if val is not None:
global_shortcuts[ac] = val
@ -191,7 +191,7 @@ class AppRunner:
def __call__(self, opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
set_scale(opts.box_drawing_scale)
set_options(opts, is_wayland(), args.debug_rendering, args.debug_font_fallback)
set_options(opts, is_wayland(), args.debug_keyboard, args.debug_rendering, args.debug_font_fallback)
try:
set_font_family(opts, debug_font_matching=args.debug_font_fallback)
_run_app(opts, args, bad_lines)

View File

@ -345,7 +345,7 @@ egr() # }}}
agr('mouse', 'Mouse')
opt('mouse_hide_wait', '3.0',
macos_default="0.0",
macos_default='0.0',
option_type='float', ctype='time',
long_text='''
Hide mouse cursor after the specified number of seconds of the mouse not being
@ -2971,7 +2971,7 @@ and clear the selection or send an interrupt if there is no selection.
)
map('Copy to clipboard',
'copy_to_clipboard cmd+c copy_to_clipboard',
only="macos",
only='macos',
documented=False,
)
@ -2980,7 +2980,7 @@ map('Paste from clipboard',
)
map('Paste from clipboard',
'paste_from_clipboard cmd+v paste_from_clipboard',
only="macos",
only='macos',
documented=False,
)
@ -3021,11 +3021,11 @@ map('Scroll line up',
)
map('Scroll line up',
'scroll_line_up opt+cmd+page_up scroll_line_up',
only="macos",
only='macos',
)
map('Scroll line up',
'scroll_line_up cmd+up scroll_line_up',
only="macos",
only='macos',
)
map('Scroll line down',
@ -3036,11 +3036,11 @@ map('Scroll line down',
)
map('Scroll line down',
'scroll_line_down opt+cmd+page_down scroll_line_down',
only="macos",
only='macos',
)
map('Scroll line down',
'scroll_line_down cmd+down scroll_line_down',
only="macos",
only='macos',
)
map('Scroll page up',
@ -3048,7 +3048,7 @@ map('Scroll page up',
)
map('Scroll page up',
'scroll_page_up cmd+page_up scroll_page_up',
only="macos",
only='macos',
)
map('Scroll page down',
@ -3056,7 +3056,7 @@ map('Scroll page down',
)
map('Scroll page down',
'scroll_page_down cmd+page_down scroll_page_down',
only="macos",
only='macos',
)
map('Scroll to top',
@ -3064,7 +3064,7 @@ map('Scroll to top',
)
map('Scroll to top',
'scroll_home cmd+home scroll_home',
only="macos",
only='macos',
)
map('Scroll to bottom',
@ -3072,7 +3072,7 @@ map('Scroll to bottom',
)
map('Scroll to bottom',
'scroll_end cmd+end scroll_end',
only="macos",
only='macos',
)
map('Scroll to previous shell prompt',
@ -3157,7 +3157,7 @@ For more details, see :doc:`launch`.
)
map('New window',
'new_window cmd+enter new_window',
only="macos",
only='macos',
)
map('New OS window',
@ -3170,7 +3170,7 @@ current working directory.
)
map('New OS window',
'new_os_window cmd+n new_os_window',
only="macos",
only='macos',
)
map('Close window',
@ -3178,7 +3178,7 @@ map('Close window',
)
map('Close window',
'close_window shift+cmd+d close_window',
only="macos",
only='macos',
)
map('Next window',
@ -3206,7 +3206,7 @@ map('Start resizing window',
)
map('Start resizing window',
'start_resizing_window cmd+r start_resizing_window',
only="macos",
only='macos',
)
map('First window',
@ -3214,7 +3214,7 @@ map('First window',
)
map('First window',
'first_window cmd+1 first_window',
only="macos",
only='macos',
)
map('Second window',
@ -3222,7 +3222,7 @@ map('Second window',
)
map('Second window',
'second_window cmd+2 second_window',
only="macos",
only='macos',
)
map('Third window',
@ -3230,7 +3230,7 @@ map('Third window',
)
map('Third window',
'third_window cmd+3 third_window',
only="macos",
only='macos',
)
map('Fourth window',
@ -3238,7 +3238,7 @@ map('Fourth window',
)
map('Fourth window',
'fourth_window cmd+4 fourth_window',
only="macos",
only='macos',
)
map('Fifth window',
@ -3246,7 +3246,7 @@ map('Fifth window',
)
map('Fifth window',
'fifth_window cmd+5 fifth_window',
only="macos",
only='macos',
)
map('Sixth window',
@ -3254,7 +3254,7 @@ map('Sixth window',
)
map('Sixth window',
'sixth_window cmd+6 sixth_window',
only="macos",
only='macos',
)
map('Seventh window',
@ -3262,7 +3262,7 @@ map('Seventh window',
)
map('Seventh window',
'seventh_window cmd+7 seventh_window',
only="macos",
only='macos',
)
map('Eight window',
@ -3270,7 +3270,7 @@ map('Eight window',
)
map('Eight window',
'eighth_window cmd+8 eighth_window',
only="macos",
only='macos',
)
map('Ninth window',
@ -3278,7 +3278,7 @@ map('Ninth window',
)
map('Ninth window',
'ninth_window cmd+9 ninth_window',
only="macos",
only='macos',
)
map('Tenth window',
@ -3298,7 +3298,7 @@ map('Next tab',
)
map('Next tab',
'next_tab shift+cmd+] next_tab',
only="macos",
only='macos',
)
map('Next tab',
'next_tab ctrl+tab next_tab',
@ -3309,7 +3309,7 @@ map('Previous tab',
)
map('Previous tab',
'previous_tab shift+cmd+[ previous_tab',
only="macos",
only='macos',
)
map('Previous tab',
'previous_tab ctrl+shift+tab previous_tab',
@ -3320,7 +3320,7 @@ map('New tab',
)
map('New tab',
'new_tab cmd+t new_tab',
only="macos",
only='macos',
)
map('Close tab',
@ -3328,12 +3328,12 @@ map('Close tab',
)
map('Close tab',
'close_tab cmd+w close_tab',
only="macos",
only='macos',
)
map('Close OS window',
'close_os_window shift+cmd+w close_os_window',
only="macos",
only='macos',
)
map('Move tab forward',
@ -3349,7 +3349,7 @@ map('Set tab title',
)
map('Set tab title',
'set_tab_title shift+cmd+i set_tab_title',
only="macos",
only='macos',
)
egr('''
You can also create shortcuts to go to specific tabs, with 1 being the first
@ -3410,15 +3410,15 @@ map('Increase font size',
)
map('Increase font size',
'increase_font_size cmd+plus change_font_size all +2.0',
only="macos",
only='macos',
)
map('Increase font size',
'increase_font_size cmd+equal change_font_size all +2.0',
only="macos",
only='macos',
)
map('Increase font size',
'increase_font_size shift+cmd+equal change_font_size all +2.0',
only="macos",
only='macos',
)
map('Decrease font size',
@ -3429,11 +3429,11 @@ map('Decrease font size',
)
map('Decrease font size',
'decrease_font_size cmd+minus change_font_size all -2.0',
only="macos",
only='macos',
)
map('Decrease font size',
'decrease_font_size shift+cmd+minus change_font_size all -2.0',
only="macos",
only='macos',
)
map('Reset font size',
@ -3441,7 +3441,7 @@ map('Reset font size',
)
map('Reset font size',
'reset_font_size cmd+0 change_font_size all 0',
only="macos",
only='macos',
)
egr('''
To setup shortcuts for specific font sizes::
@ -3534,12 +3534,17 @@ map('Toggle maximized',
'toggle_maximized kitty_mod+f10 toggle_maximized',
)
map('Toggle macOS secure keyboard entry',
'toggle_macos_secure_keyboard_entry opt+cmd+s toggle_macos_secure_keyboard_entry',
only='macos',
)
map('Unicode input',
'input_unicode_character kitty_mod+u kitten unicode_input',
)
map('Unicode input',
'input_unicode_character ctrl+cmd+space kitten unicode_input',
only="macos",
only='macos',
)
map('Edit config file',
@ -3547,7 +3552,7 @@ map('Edit config file',
)
map('Edit config file',
'edit_config_file cmd+, edit_config_file',
only="macos",
only='macos',
)
map('Open the kitty command shell',
@ -3609,7 +3614,7 @@ screen, for example, for ZSH add the following to :file:`~/.zshrc`:
map('Reset the terminal',
'reset_terminal opt+cmd+r clear_terminal reset active',
only="macos",
only='macos',
)
map('Reload kitty.conf',

View File

@ -898,6 +898,7 @@ if is_macos:
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=45), definition='change_font_size all -2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=9, key=45), definition='change_font_size all -2.0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=48), definition='change_font_size all 0')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=115), definition='toggle_macos_secure_keyboard_entry')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=12, key=32), definition='kitten unicode_input')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=8, key=44), definition='edit_config_file')) # noqa
defaults.map.append(KeyDefinition(trigger=SingleKey(mods=10, key=114), definition='clear_terminal reset active')) # noqa

View File

@ -684,8 +684,8 @@ PYWRAP0(get_options) {
PYWRAP1(set_options) {
PyObject *opts;
int is_wayland = 0, debug_rendering = 0, debug_font_fallback = 0;
PA("O|ppp", &opts, &is_wayland, &debug_rendering, &debug_font_fallback);
int is_wayland = 0, debug_keyboard = 0, debug_rendering = 0, debug_font_fallback = 0;
PA("O|pppp", &opts, &is_wayland, &debug_keyboard, &debug_rendering, &debug_font_fallback);
if (opts == Py_None) {
Py_CLEAR(options_object);
Py_RETURN_NONE;
@ -695,6 +695,7 @@ PYWRAP1(set_options) {
global_state.has_render_frames = true;
#endif
if (global_state.is_wayland) global_state.has_render_frames = true;
global_state.debug_keyboard = debug_keyboard ? true : false;
global_state.debug_rendering = debug_rendering ? true : false;
global_state.debug_font_fallback = debug_font_fallback ? true : false;
if (!convert_opts_from_python_opts(opts, &global_state.opts)) return NULL;
@ -821,6 +822,11 @@ PYWRAP1(focus_os_window) {
Py_RETURN_FALSE;
}
PYWRAP0(toggle_secure_input) {
toggle_secure_input();
Py_RETURN_NONE;
}
PYWRAP1(set_titlebar_color) {
id_type os_window_id;
unsigned int color;
@ -1266,6 +1272,7 @@ static PyMethodDef module_methods[] = {
MW(current_application_quit_request, METH_NOARGS),
MW(set_titlebar_color, METH_VARARGS),
MW(focus_os_window, METH_VARARGS),
MW(toggle_secure_input, METH_NOARGS),
MW(mark_tab_bar_dirty, METH_O),
MW(change_background_opacity, METH_VARARGS),
MW(background_opacity_of, METH_O),

View File

@ -224,7 +224,7 @@ typedef struct {
OSWindow *callback_os_window;
bool is_wayland;
bool has_render_frames;
bool debug_rendering, debug_font_fallback;
bool debug_keyboard, debug_rendering, debug_font_fallback;
bool has_pending_resizes, has_pending_closes;
bool in_sequence_mode;
bool check_for_active_animated_images;
@ -262,6 +262,7 @@ void hide_mouse(OSWindow *w);
bool is_mouse_hidden(OSWindow *w);
void destroy_os_window(OSWindow *w);
void focus_os_window(OSWindow *w, bool also_raise);
void toggle_secure_input(void);
void set_os_window_title(OSWindow *w, const char *title);
OSWindow* os_window_for_kitty_window(id_type);
OSWindow* add_os_window(void);
@ -303,6 +304,7 @@ typedef enum {
CLOSE_WINDOW,
RESET_TERMINAL,
RELOAD_CONFIG,
TOGGLE_MACOS_SECURE_KEYBOARD_ENTRY,
NUM_COCOA_PENDING_ACTIONS
} CocoaPendingAction;

View File

@ -416,7 +416,7 @@ def kitty_env() -> Env:
cflags.extend(pkg_config('lcms2', '--cflags-only-I'))
if is_macos:
platform_libs = [
'-framework', 'CoreText', '-framework', 'CoreGraphics',
'-framework', 'Carbon', '-framework', 'CoreText', '-framework', 'CoreGraphics',
]
test_program_src = '''#include <UserNotifications/UserNotifications.h>
int main(void) { return 0; }\n'''