Merge pull request #4691 from atom/ks-improve-middle-mouse-paste

Improve middle mouse paste on Linux
This commit is contained in:
Kevin Sawicki
2014-12-18 11:23:47 -08:00
2 changed files with 46 additions and 27 deletions

View File

@@ -2713,26 +2713,35 @@ describe "TextEditorComponent", ->
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
describe "middle mouse paste on Linux", ->
it "pastes the previously selected text", ->
originalPlatform = null
beforeEach ->
originalPlatform = process.platform
Object.defineProperty process, 'platform', value: 'linux'
afterEach ->
Object.defineProperty process, 'platform', value: originalPlatform
it "pastes the previously selected text at the clicked location", ->
jasmine.unspy(window, 'setTimeout')
clipboardWrittenTo = false
spyOn(require('ipc'), 'send').andCallFake (eventName, selectedText) ->
if eventName is 'write-text-to-selection-clipboard'
require('clipboard').writeText(selectedText, 'selection')
clipboardWrittenTo = true
atom.clipboard.write('')
component.listenForMiddleMousePaste()
editor.setCursorBufferPosition([10, 0])
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
expect(atom.clipboard.read()).toBe ''
expect(editor.lineTextForBufferRow(10)).toBe ''
component.trackSelectionClipboard()
editor.setSelectedBufferRange([[1, 6], [1, 10]])
editor.setCursorBufferPosition([10, 0])
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
waitsFor ->
clipboardWrittenTo
runs ->
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([10, 0]), button: 1))
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([10, 0]), which: 2))
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
buildMouseEvent = (type, properties...) ->
properties = extend({bubbles: true, cancelable: true}, properties...)

View File

@@ -404,7 +404,7 @@ TextEditorComponent = React.createClass
window.addEventListener 'resize', @requestHeightAndWidthMeasurement
@listenForIMEEvents()
@listenForMiddleMousePaste() if process.platform is 'linux'
@trackSelectionClipboard() if process.platform is 'linux'
listenForIMEEvents: ->
node = @getDOMNode()
@@ -432,21 +432,21 @@ TextEditorComponent = React.createClass
editor.insertText(selectedText, select: true, undo: 'skip')
event.target.value = ''
listenForMiddleMousePaste: ->
clipboard = require 'clipboard'
@refs.scrollView.getDOMNode().addEventListener 'mouseup', ({which}) =>
return unless which is 2
if selection = clipboard.readText('selection')
@props.editor.insertText(selection)
@subscribe @props.editor.onDidChangeSelectionRange =>
if selectedText = @props.editor.getSelectedText()
# Listen for selection changes and store the currently selected text
# in the selection clipboard. This is only applicable on Linux.
trackSelectionClipboard: ->
timeoutId = null
{editor} = @props
writeSelectedTextToSelectionClipboard = =>
return if editor.isDestroyed()
if selectedText = editor.getSelectedText()
# This uses ipc.send instead of clipboard.writeText because
# clipboard.writeText is a sync ipc call on Linux and that
# will slow down selections.
ipc.send('write-text-to-selection-clipboard', selectedText)
@subscribe editor.onDidChangeSelectionRange ->
clearTimeout(timeoutId)
timeoutId = setTimeout(writeSelectedTextToSelectionClipboard)
observeConfig: ->
@subscribe atom.config.observe 'editor.useHardwareAcceleration', @setUseHardwareAcceleration
@@ -560,7 +560,11 @@ TextEditorComponent = React.createClass
scrollViewNode.scrollLeft = 0
onMouseDown: (event) ->
return unless event.button is 0 # only handle the left mouse button
unless event.button is 0 or (event.button is 1 and process.platform is 'linux')
# Only handle mouse down events for left mouse button on all platforms
# and middle mouse button on Linux since it pastes the selection clipboard
return
return if event.target?.classList.contains('horizontal-scrollbar')
{editor} = @props
@@ -769,15 +773,21 @@ TextEditorComponent = React.createClass
# Stop dragging when cursor enters dev tools because we can't detect mouseup
onMouseUp() if event.which is 0
onMouseUp = ->
onMouseUp = (event) ->
stopDragging()
editor.finalizeSelections()
pasteSelectionClipboard(event)
stopDragging = ->
dragging = false
window.removeEventListener('mousemove', onMouseMove)
window.removeEventListener('mouseup', onMouseUp)
pasteSelectionClipboard = (event) ->
if event?.which is 2 and process.platform is 'linux'
if selection = require('clipboard').readText('selection')
editor.insertText(selection)
window.addEventListener('mousemove', onMouseMove)
window.addEventListener('mouseup', onMouseUp)