-
Notifications
You must be signed in to change notification settings - Fork 136
Fix down arrow key not working after font size change #364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -204,13 +204,17 @@ | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| func handleEvent(event: NSEvent) -> NSEvent? { | ||||||||||||||||||||||
| let modifierFlags = event.modifierFlags.intersection(.deviceIndependentFlagsMask) | ||||||||||||||||||||||
| switch event.type { | ||||||||||||||||||||||
| case .keyDown: | ||||||||||||||||||||||
| let tabKey: UInt16 = 0x30 | ||||||||||||||||||||||
| let downArrow: UInt16 = 125 | ||||||||||||||||||||||
| let upArrow: UInt16 = 126 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if event.keyCode == tabKey { | ||||||||||||||||||||||
| if event.keyCode == downArrow || event.keyCode == upArrow { | ||||||||||||||||||||||
| return self.handleArrowKey(event: event, modifierFlags: modifierFlags) | ||||||||||||||||||||||
| } else if event.keyCode == tabKey { | ||||||||||||||||||||||
| return self.handleTab(event: event, modifierFlags: modifierFlags.rawValue) | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| return self.handleCommand(event: event, modifierFlags: modifierFlags) | ||||||||||||||||||||||
|
|
@@ -243,7 +247,7 @@ | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| func handleCommand(event: NSEvent, modifierFlags: NSEvent.ModifierFlags) -> NSEvent? { | ||||||||||||||||||||||
| let commandKey = NSEvent.ModifierFlags.command | ||||||||||||||||||||||
| let controlKey = NSEvent.ModifierFlags.control | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -276,11 +280,64 @@ | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| jumpToDefinitionModel.performJump(at: cursor.range) | ||||||||||||||||||||||
| return nil | ||||||||||||||||||||||
| case (controlKey, "n"): | ||||||||||||||||||||||
| self.textView.moveDown(nil) | ||||||||||||||||||||||
| return nil | ||||||||||||||||||||||
| case (controlKey, "p"): | ||||||||||||||||||||||
| self.textView.moveUp(nil) | ||||||||||||||||||||||
| return nil | ||||||||||||||||||||||
| case (_, _): | ||||||||||||||||||||||
| return event | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Handles up/down arrow key events with all modifier combinations. | ||||||||||||||||||||||
| /// Dispatches the appropriate movement method on the text view and consumes the event. | ||||||||||||||||||||||
| /// | ||||||||||||||||||||||
| /// - Returns: `nil` to consume the event after dispatching the movement action. | ||||||||||||||||||||||
|
||||||||||||||||||||||
| /// Handles up/down arrow key events with all modifier combinations. | |
| /// Dispatches the appropriate movement method on the text view and consumes the event. | |
| /// | |
| /// - Returns: `nil` to consume the event after dispatching the movement action. | |
| /// Handles up/down arrow key events for plain, Shift, Option, Command, | |
| /// and their combinations among these modifiers. | |
| /// Dispatches the appropriate movement method on the text view and consumes the event. | |
| /// | |
| /// - Returns: `nil` to consume the event after dispatching the movement action, | |
| /// or the original event for unsupported modifier combinations. |
Outdated
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handleEvent defines downArrow/upArrow constants, but handleArrowKey re-hardcodes 125 to compute isDown. To reduce magic numbers and keep key-code mapping consistent, reuse the same constants (or centralize them) instead of duplicating the raw value.
| let isDown = event.keyCode == 125 | |
| let downArrow: UInt16 = 125 | |
| let upArrow: UInt16 = 126 | |
| let isDown = event.keyCode == downArrow |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,11 @@ extension SourceEditorConfiguration { | |
| controller.textView.font = font | ||
| controller.textView.typingAttributes = controller.attributesFor(nil) | ||
| controller.gutterView.font = font.rulerFont | ||
| // Force the layout manager to recalculate its cached estimated line height. | ||
| // The estimate is cached and not invalidated by font changes, causing vertical | ||
| // cursor movement (moveDown:) to use stale values and fail to cross line boundaries. | ||
| let renderDelegate = controller.textView.layoutManager.renderDelegate | ||
| controller.textView.layoutManager.renderDelegate = renderDelegate | ||
|
||
| needsHighlighterInvalidation = true | ||
| } | ||
|
|
||
|
|
@@ -103,6 +108,9 @@ extension SourceEditorConfiguration { | |
|
|
||
| if oldConfig?.lineHeightMultiple != lineHeightMultiple { | ||
| controller.textView.layoutManager.lineHeightMultiplier = lineHeightMultiple | ||
| // Also invalidate the cached estimated line height (same issue as font change above). | ||
| let renderDelegate = controller.textView.layoutManager.renderDelegate | ||
| controller.textView.layoutManager.renderDelegate = renderDelegate | ||
|
||
| } | ||
|
|
||
| if oldConfig?.wrapLines != wrapLines { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new Ctrl-N / Ctrl-P shortcuts match only when
modifierFlagsequals exactly.control. BecausemodifierFlagsis built from.deviceIndependentFlagsMask, it can include extra flags (e.g. Caps Lock / Fn / numericPad), which would prevent these bindings from firing. Consider normalizing the flags to only [.shift, .control, .option, .command] before switching, or using.contains(.control)with explicit exclusions for other modifiers as needed.