Fix shift-scroll on Windows and Linux

This commit is contained in:
Antonio Scandurra
2017-04-21 12:29:33 +02:00
parent 906b3b05d6
commit 72d6316459
2 changed files with 144 additions and 12 deletions

View File

@@ -842,6 +842,126 @@ describe('TextEditorComponent', () => {
})
})
describe('scrolling via the mouse wheel', () => {
it('scrolls vertically when deltaY is not 0', () => {
const mouseWheelScrollSensitivity = 0.4
const {component, editor} = buildComponent({height: 50, mouseWheelScrollSensitivity})
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
}
{
const expectedScrollTop = component.getScrollTop() - (10 * mouseWheelScrollSensitivity)
component.didMouseWheel({deltaX: 0, deltaY: -10})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
}
})
it('scrolls horizontally when deltaX is not 0', () => {
const mouseWheelScrollSensitivity = 0.4
const {component, editor} = buildComponent({width: 50, mouseWheelScrollSensitivity})
{
const expectedScrollLeft = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 20, deltaY: 0})
expect(component.getScrollLeft()).toBe(expectedScrollLeft)
expect(component.refs.content.style.transform).toBe(`translate(-${expectedScrollLeft}px, 0px)`)
}
{
const expectedScrollLeft = component.getScrollLeft() - (10 * mouseWheelScrollSensitivity)
component.didMouseWheel({deltaX: -10, deltaY: 0})
expect(component.getScrollLeft()).toBe(expectedScrollLeft)
expect(component.refs.content.style.transform).toBe(`translate(-${expectedScrollLeft}px, 0px)`)
}
})
it('inverts deltaX and deltaY when holding shift on Windows and Linux', async () => {
const mouseWheelScrollSensitivity = 0.4
const {component, editor} = buildComponent({height: 50, width: 50, mouseWheelScrollSensitivity})
component.props.platform = 'linux'
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
await setScrollTop(component, 0)
}
{
const expectedScrollLeft = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20, shiftKey: true})
expect(component.getScrollLeft()).toBe(expectedScrollLeft)
expect(component.refs.content.style.transform).toBe(`translate(-${expectedScrollLeft}px, 0px)`)
await setScrollLeft(component, 0)
}
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 20, deltaY: 0, shiftKey: true})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
await setScrollTop(component, 0)
}
component.props.platform = 'win32'
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
await setScrollTop(component, 0)
}
{
const expectedScrollLeft = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20, shiftKey: true})
expect(component.getScrollLeft()).toBe(expectedScrollLeft)
expect(component.refs.content.style.transform).toBe(`translate(-${expectedScrollLeft}px, 0px)`)
await setScrollLeft(component, 0)
}
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 20, deltaY: 0, shiftKey: true})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
await setScrollTop(component, 0)
}
component.props.platform = 'darwin'
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
await setScrollTop(component, 0)
}
{
const expectedScrollTop = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 0, deltaY: 20, shiftKey: true})
expect(component.getScrollTop()).toBe(expectedScrollTop)
expect(component.refs.content.style.transform).toBe(`translate(0px, -${expectedScrollTop}px)`)
await setScrollTop(component, 0)
}
{
const expectedScrollLeft = 20 * mouseWheelScrollSensitivity
component.didMouseWheel({deltaX: 20, deltaY: 0, shiftKey: true})
expect(component.getScrollLeft()).toBe(expectedScrollLeft)
expect(component.refs.content.style.transform).toBe(`translate(-${expectedScrollLeft}px, 0px)`)
await setScrollLeft(component, 0)
}
})
})
describe('line and line number decorations', () => {
it('adds decoration classes on screen lines spanned by decorated markers', async () => {
const {component, element, editor} = buildComponent({width: 435, attach: false})
@@ -2974,7 +3094,8 @@ function buildComponent (params = {}) {
model: editor,
rowsPerTile: params.rowsPerTile,
updatedSynchronously: false,
platform: params.platform
platform: params.platform,
mouseWheelScrollSensitivity: params.mouseWheelScrollSensitivity
})
const {element} = component
if (!editor.getAutoHeight()) {

View File

@@ -19,7 +19,6 @@ const KOREAN_CHARACTER = '세'
const NBSP_CHARACTER = '\u00a0'
const ZERO_WIDTH_NBSP_CHARACTER = '\ufeff'
const MOUSE_DRAG_AUTOSCROLL_MARGIN = 40
const MOUSE_WHEEL_SCROLL_SENSITIVITY = 0.8
const CURSOR_BLINK_RESUME_DELAY = 300
const CURSOR_BLINK_PERIOD = 800
@@ -1361,9 +1360,17 @@ class TextEditorComponent {
}
didMouseWheel (event) {
const scrollSensitivity = this.props.mouseWheelScrollSensitivity || 0.8
let {deltaX, deltaY} = event
deltaX = deltaX * MOUSE_WHEEL_SCROLL_SENSITIVITY
deltaY = deltaY * MOUSE_WHEEL_SCROLL_SENSITIVITY
deltaX = deltaX * scrollSensitivity
deltaY = deltaY * scrollSensitivity
if (this.getPlatform() !== 'darwin' && event.shiftKey) {
let temp = deltaX
deltaX = deltaY
deltaY = temp
}
const scrollPositionChanged =
this.setScrollLeft(this.getScrollLeft() + deltaX) ||
@@ -1514,12 +1521,12 @@ class TextEditorComponent {
}
didMouseDownOnContent (event) {
const {model, platform} = this.props
const {model} = this.props
const {target, button, detail, ctrlKey, shiftKey, metaKey} = event
// Only handle mousedown events for left mouse button (or the middle mouse
// button on Linux where it pastes the selection clipboard).
if (!(button === 0 || (platform === 'linux' && button === 1))) return
if (!(button === 0 || (this.getPlatform() === 'linux' && button === 1))) return
const screenPosition = this.screenPositionForMouseEvent(event)
@@ -1530,14 +1537,14 @@ class TextEditorComponent {
}
// Handle middle mouse button only on Linux (paste clipboard)
if (platform === 'linux' && button === 1) {
if (this.getPlatform() === 'linux' && button === 1) {
const selection = clipboard.readText('selection')
model.setCursorScreenPosition(screenPosition, {autoscroll: false})
model.insertText(selection)
return
}
const addOrRemoveSelection = metaKey || (ctrlKey && platform !== 'darwin')
const addOrRemoveSelection = metaKey || (ctrlKey && this.getPlatform() !== 'darwin')
switch (detail) {
case 1:
@@ -1582,7 +1589,7 @@ class TextEditorComponent {
}
didMouseDownOnLineNumberGutter (event) {
const {model, platform} = this.props
const {model} = this.props
const {target, button, ctrlKey, shiftKey, metaKey} = event
// Only handle mousedown events for left mouse button
@@ -1596,7 +1603,7 @@ class TextEditorComponent {
return
}
const addOrRemoveSelection = metaKey || (ctrlKey && platform !== 'darwin')
const addOrRemoveSelection = metaKey || (ctrlKey && this.getPlatform() !== 'darwin')
const endBufferRow = model.bufferPositionForScreenPosition([clickedScreenRow, Infinity]).row
const clickedLineBufferRange = Range(Point(startBufferRow, 0), Point(endBufferRow + 1, 0))
@@ -2181,9 +2188,9 @@ class TextEditorComponent {
}
didChangeSelectionRange () {
const {model, platform} = this.props
const {model} = this.props
if (platform === 'linux') {
if (this.getPlatform() === 'linux') {
if (this.selectionClipboardImmediateId) {
clearImmediate(this.selectionClipboardImmediateId)
}
@@ -2568,6 +2575,10 @@ class TextEditorComponent {
isInputEnabled (inputEnabled) {
return this.props.inputEnabled != null ? this.props.inputEnabled : true
}
getPlatform () {
return this.props.platform || process.platform
}
}
class DummyScrollbarComponent {