From 10c529ab16344795785c99fbde067e5b9c87f248 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sat, 31 Oct 2020 23:31:56 -0500
Subject: [PATCH 01/26] perf improvement MVP
See last batch of comments on #24, also uses code from https://gist.github.com/romgrk/56169975ccd8fa2ffafd134afcdfeedc
---
src/render/redraw.ts | 25 +++++++++++++++++--------
src/windows/window-manager.ts | 9 +++++++++
src/windows/window.ts | 12 +++++++++++-
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index 58fcc3b9..7dab02b1 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -307,6 +307,20 @@ const win_float_pos = (e: any) => {
}
}
+let layoutTimeout: NodeJS.Timeout | undefined
+
+const refreshOrStartLayoutTimer = (winUpdates: boolean) => {
+ layoutTimeout = setTimeout(() => {
+ state_cursorVisible ? showCursor() : hideCursor()
+ if (state_cursorVisible) updateCursorChar()
+ dispatch.pub('redraw')
+ if (!winUpdates) return
+
+ windows.disposeInvalidWindows()
+ windows.layout()
+ }, 10)
+}
+
onRedraw((redrawEvents) => {
// because of circular logic/infinite loop. cmdline_show updates UI, UI makes
// a change in the cmdline, nvim sends redraw again. we cut that stuff out
@@ -317,6 +331,7 @@ onRedraw((redrawEvents) => {
const messageEvents: any = []
const eventCount = redrawEvents.length
+
for (let ix = 0; ix < eventCount; ix++) {
const ev = redrawEvents[ix]
const e = ev[0]
@@ -373,12 +388,6 @@ onRedraw((redrawEvents) => {
renderEvents.messageClearPromptsMaybeHack(state_cursorVisible)
- requestAnimationFrame(() => {
- state_cursorVisible ? showCursor() : hideCursor()
- if (state_cursorVisible) updateCursorChar()
- dispatch.pub('redraw')
- if (!winUpdates) return
- windows.disposeInvalidWindows()
- windows.layout()
- })
+ if (!layoutTimeout) refreshOrStartLayoutTimer(winUpdates)
+ else clearTimeout(layoutTimeout), refreshOrStartLayoutTimer(winUpdates)
})
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index be87fe99..bb7f3c44 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -32,7 +32,16 @@ const getWindowById = (windowId: number) => {
const getInstanceWindows = (id = instances.current) =>
[...windows.values()].filter((win) => win.id.startsWith(`i${id}`))
+let webglTimeout: NodeJS.Timeout | undefined;
+
const refreshWebGLGrid = () => {
+ if (webglTimeout)
+ clearTimeout(webglTimeout)
+ webglTimeout = setTimeout(refreshWebGLGridImplementation, 15)
+}
+
+const refreshWebGLGridImplementation = () => {
+ webglTimeout = undefined
webgl.clearAll()
getInstanceWindows().forEach((w) => w.redrawFromGridBuffer())
}
diff --git a/src/windows/window.ts b/src/windows/window.ts
index 0649a1d2..ecf9cf3f 100644
--- a/src/windows/window.ts
+++ b/src/windows/window.ts
@@ -161,6 +161,8 @@ export default () => {
container.appendChild(nameplate.element)
container.appendChild(content)
+ const dimensions = new WeakMap()
+
const api = {
get id() {
return wininfo.id
@@ -278,7 +280,15 @@ export default () => {
}
api.refreshLayout = () => {
- const { top, left, width, height } = content.getBoundingClientRect()
+ let rect
+ if (dimensions.has(content)) {
+ rect = dimensions.get(content)
+ }
+ else {
+ rect = content.getBoundingClientRect()
+ dimensions.set(content, rect)
+ }
+ const { top, left, width, height } = rect
const x = left
const y = top - titleSpecs.height
From dddcb56602af7b5692173e4910b5999087b25614 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 00:16:37 -0500
Subject: [PATCH 02/26] Initial impl for webgl cursor
breaks things, still very much a WIP
---
src/core/cursor.ts | 6 +++---
src/render/redraw.ts | 3 +--
src/render/webgl-text-bg.ts | 25 +++++++++++++++++++++++--
src/render/webgl.ts | 4 ++++
4 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index a68e2a14..34378374 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -21,8 +21,8 @@ const cursorChar = document.createElement('span')
const cursorline = document.getElementById('cursorline') as HTMLElement
export const debugline = document.getElementById('debugline') as HTMLElement
let cursorRequestedToBeHidden = false
-let cursorEnabled = true
-let cursorCharVisible = true
+let cursorEnabled = false
+let cursorCharVisible = false
Object.assign(cursorline.style, {
background: 'rgba(var(--background-alpha), 0.2)',
@@ -90,7 +90,7 @@ export const setCursorColor = (color: string) => {
cursorEl.style.background = color
}
-export const enableCursor = () => (cursorEnabled = true)
+export const enableCursor = () => (cursorEnabled = false)
export const disableCursor = () => (cursorEnabled = false)
export const hideCursor = () => {
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index 7dab02b1..56650017 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -8,7 +8,6 @@ import {
getUpdatedFontAtlasMaybe,
} from '../render/font-texture-atlas'
import {
- moveCursor,
hideCursor,
showCursor,
updateCursorChar,
@@ -92,7 +91,7 @@ const grid_cursor_goto = ([, [gridId, row, col]]: any) => {
state_cursorVisible = gridId !== 1
if (gridId === 1) return
windows.setActiveGrid(gridId)
- moveCursor(gridId, row, col)
+ windows.webgl.updateCursorPosition(row, col)
}
const grid_scroll = ([
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 6e8b0acc..cf82003a 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -2,6 +2,7 @@ import { getColorAtlas, colors } from '../render/highlight-attributes'
import { WebGL, VarKind } from '../render/webgl-utils'
import { cell } from '../core/workspace'
import { hexToRGB } from '../ui/css'
+import { cursor } from '../core/cursor'
export default (webgl: WebGL) => {
const viewport = { x: 0, y: 0, width: 0, height: 0 }
@@ -15,6 +16,7 @@ export default (webgl: WebGL) => {
colorAtlasResolution: VarKind.Uniform,
colorAtlasTextureId: VarKind.Uniform,
cellSize: VarKind.Uniform,
+ cursorPosition: VarKind.Uniform,
})
program.setVertexShader(
@@ -22,6 +24,7 @@ export default (webgl: WebGL) => {
in vec2 ${v.quadVertex};
in vec2 ${v.cellPosition};
in float ${v.hlid};
+ uniform vec2 ${v.cursorPosition};
uniform vec2 ${v.canvasResolution};
uniform vec2 ${v.colorAtlasResolution};
uniform vec2 ${v.cellSize};
@@ -44,7 +47,12 @@ export default (webgl: WebGL) => {
float color_y = ${v.hlidType} * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- o_color = texture(${v.colorAtlasTextureId}, colorPosition);
+ vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
+ if (${v.cursorPosition} == ${v.cellPosition}) {
+ o_color = vec4(1.0 - textureColor.r, 1.0 - textureColor.g, 1.0 - textureColor.b, 1);
+ } else {
+ o_color = textureColor;
+ }
}
`
)
@@ -75,6 +83,11 @@ export default (webgl: WebGL) => {
colorAtlas.width,
colorAtlas.height
)
+ webgl.gl.uniform2f(
+ program.vars.cursorPosition,
+ 0,
+ 0,
+ )
// total size of all pointers. chunk size that goes to shader
const wrenderStride = 4 * Float32Array.BYTES_PER_ELEMENT
@@ -194,6 +207,14 @@ export default (webgl: WebGL) => {
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
}
+ const updateCursorPosition = (row: number, col: number) => {
+ webgl.gl.uniform2f(
+ program.vars.cursorPosition,
+ col,
+ row,
+ )
+ }
+
const updateColorAtlas = (colorAtlas: HTMLCanvasElement) => {
webgl.loadCanvasTexture(colorAtlas, webgl.gl.TEXTURE0)
webgl.gl.uniform2f(
@@ -222,5 +243,5 @@ export default (webgl: WebGL) => {
webgl.gl.clear(webgl.gl.COLOR_BUFFER_BIT)
}
- return { clear, clearAll, render, resize, updateColorAtlas, updateCellSize }
+ return { clear, clearAll, render, resize, updateColorAtlas, updateCellSize, updateCursorPosition }
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 41eb3a71..7a4d30fc 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -31,6 +31,9 @@ const nutella = () => {
textFGRenderer.resize(width, height)
}
+ const updateCursorPosition = (row: number, col: number) =>
+ textBGRenderer.updateCursorPosition(row, col)
+
const updateFontAtlas = (fontAtlas: HTMLCanvasElement) => {
textFGRenderer.updateFontAtlas(fontAtlas)
}
@@ -143,6 +146,7 @@ const nutella = () => {
updateCellSize,
updateFontAtlas,
updateColorAtlas,
+ updateCursorPosition,
foregroundElement: foregroundGL.canvasElement,
backgroundElement: backgroundGL.canvasElement,
}
From 1aaf7c2b7ffa1a681ffd11e69017c8885ace2209 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 09:48:01 -0600
Subject: [PATCH 03/26] More webgl cursor stuff
---
src/core/cursor.ts | 133 +++++++++++-------------------------
src/render/webgl-text-bg.ts | 34 +++++----
src/render/webgl.ts | 4 ++
3 files changed, 66 insertions(+), 105 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index 34378374..a5d3665d 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -2,6 +2,7 @@ import * as windows from '../windows/window-manager'
import { partialFill, translate } from '../ui/css'
import { paddingX } from '../windows/window'
import { cell } from '../core/workspace'
+import { hexToRGB } from '../ui/css'
export enum CursorShape {
block,
@@ -12,82 +13,30 @@ export enum CursorShape {
export const cursor = {
row: 0,
col: 0,
- color: '#fff',
+ color: [0, 0, 0],
shape: CursorShape.block,
}
-const cursorEl = document.getElementById('cursor') as HTMLElement
-const cursorChar = document.createElement('span')
-const cursorline = document.getElementById('cursorline') as HTMLElement
-export const debugline = document.getElementById('debugline') as HTMLElement
let cursorRequestedToBeHidden = false
let cursorEnabled = false
let cursorCharVisible = false
-Object.assign(cursorline.style, {
- background: 'rgba(var(--background-alpha), 0.2)',
- position: 'absolute',
- 'mix-blend-mode': 'screen',
- height: `${cell.height}px`,
- 'z-index': 60,
-})
-
-Object.assign(debugline.style, {
- display: 'none',
- position: 'absolute',
- 'mix-blend-mode': 'screen',
- height: `${cell.height}px`,
- 'z-index': 60,
-})
-
-Object.assign(cursorEl.style, {
- 'z-index': 70,
- position: 'absolute',
- display: 'none',
- 'justify-content': 'center',
- 'align-items': 'center',
-})
-
-Object.assign(cursorChar.style, {
- filter: 'invert(1) grayscale(1)',
- 'font-family': 'var(--font)',
- 'font-size': 'calc(var(--font-size) * 1px)',
-})
-
-cursorEl.appendChild(cursorChar)
-
-export const getCursorBoundingClientRect = () =>
- cursorline.getBoundingClientRect()
-
-export const setCursorShape = (shape: CursorShape, size = 20) => {
- cursor.shape = shape
+// export const getCursorBoundingClientRect = () =>
+ // cursorline.getBoundingClientRect()
- if (shape === CursorShape.block)
- Object.assign(cursorEl.style, {
- background: cursor.color,
- height: `${cell.height}px`,
- width: `${cell.width}px`,
- })
-
- if (shape === CursorShape.line)
- Object.assign(cursorEl.style, {
- background: cursor.color,
- height: `${cell.height}px`,
- width: `${(cell.width * (size / 100)).toFixed(2)}px`,
- })
-
- if (shape === CursorShape.underline)
- Object.assign(cursorEl.style, {
- background: partialFill('horizontal', cursor.color, size),
- height: `${cell.height}px`,
- width: `${cell.width}px`,
- })
+export const setCursorShape = (shape: CursorShape) => {
+ cursor.shape = shape
}
export const setCursorColor = (color: string) => {
- cursorChar.style.color = color
- cursor.color = color
- cursorEl.style.background = color
+ let [r, g, b] = hexToRGB(color)
+ r /= 255
+ g /= 255
+ b /= 255
+ cursor.color = [r, g, b]
+
+ console.log('update cursor color', color, `rgb: ${r}, ${g}, ${b}`)
+ windows.webgl.updateCursorColor(r, g, b)
}
export const enableCursor = () => (cursorEnabled = false)
@@ -97,42 +46,42 @@ export const hideCursor = () => {
if (!cursorEnabled) return
cursorRequestedToBeHidden = true
- cursorEl.style.display = 'none'
- cursorline.style.display = 'none'
+ // cursorEl.style.display = 'none'
+ // cursorline.style.display = 'none'
}
export const showCursor = () => {
if (!cursorEnabled) return
cursorRequestedToBeHidden = false
- cursorEl.style.display = 'flex'
- cursorline.style.display = 'none'
+ // cursorEl.style.display = 'flex'
+ // cursorline.style.display = 'none'
}
export const showCursorline = () => (cursorline.style.display = '')
export const updateCursorChar = () => {
- cursorChar.innerText =
- cursor.shape === CursorShape.block
- ? windows.getActive().editor.getChar(cursor.row, cursor.col)
- : ''
+ // cursorChar.innerText =
+ // cursor.shape === CursorShape.block
+ // ? windows.getActive().editor.getChar(cursor.row, cursor.col)
+ // : ''
- if (cursor.shape === CursorShape.block && !cursorCharVisible)
- cursorChar.style.display = ''
+ // if (cursor.shape === CursorShape.block && !cursorCharVisible)
+ // cursorChar.style.display = ''
}
const updateCursorCharInternal = (gridId: number, row: number, col: number) => {
- if (cursor.shape !== CursorShape.block) {
- cursorChar.style.display = 'none'
- cursorCharVisible = false
- cursorChar.innerText = ''
- return
- }
-
- const char = windows.get(gridId).editor.getChar(row, col)
- cursorChar.innerText = char
- cursorChar.style.display = ''
- cursorCharVisible = true
+ // if (cursor.shape !== CursorShape.block) {
+ // cursorChar.style.display = 'none'
+ // cursorCharVisible = false
+ // cursorChar.innerText = ''
+ // return
+ // }
+
+ // const char = windows.get(gridId).editor.getChar(row, col)
+ // cursorChar.innerText = char
+ // cursorChar.style.display = ''
+ // cursorCharVisible = true
}
export const moveCursor = (gridId: number, row: number, col: number) => {
@@ -146,13 +95,13 @@ export const moveCursor = (gridId: number, row: number, col: number) => {
const linePos = win.positionToWorkspacePixels(row, 0)
const { width } = win.getWindowSize()
- cursorEl.style.transform = translate(cursorPos.x, cursorPos.y)
+ // cursorEl.style.transform = translate(cursorPos.x, cursorPos.y)
- Object.assign(cursorline.style, {
- transform: translate(linePos.x - paddingX, linePos.y),
- width: `${width}px`,
- height: `${cell.height}px`,
- })
+ // Object.assign(cursorline.style, {
+ // transform: translate(linePos.x - paddingX, linePos.y),
+ // width: `${width}px`,
+ // height: `${cell.height}px`,
+ // })
updateCursorCharInternal(gridId, row, col)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index cf82003a..cbbc8bdd 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -17,6 +17,7 @@ export default (webgl: WebGL) => {
colorAtlasTextureId: VarKind.Uniform,
cellSize: VarKind.Uniform,
cursorPosition: VarKind.Uniform,
+ cursorColor: VarKind.Uniform,
})
program.setVertexShader(
@@ -28,6 +29,7 @@ export default (webgl: WebGL) => {
uniform vec2 ${v.canvasResolution};
uniform vec2 ${v.colorAtlasResolution};
uniform vec2 ${v.cellSize};
+ uniform vec4 ${v.cursorColor};
uniform float ${v.hlidType};
uniform sampler2D ${v.colorAtlasTextureId};
@@ -47,10 +49,10 @@ export default (webgl: WebGL) => {
float color_y = ${v.hlidType} * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
if (${v.cursorPosition} == ${v.cellPosition}) {
- o_color = vec4(1.0 - textureColor.r, 1.0 - textureColor.g, 1.0 - textureColor.b, 1);
+ o_color = cursorColor;
} else {
+ vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
o_color = textureColor;
}
}
@@ -83,11 +85,8 @@ export default (webgl: WebGL) => {
colorAtlas.width,
colorAtlas.height
)
- webgl.gl.uniform2f(
- program.vars.cursorPosition,
- 0,
- 0,
- )
+ webgl.gl.uniform2f(program.vars.cursorPosition, 0, 0)
+ webgl.gl.uniform4fv(program.vars.cursorColor, [0, 0, 0, 1])
// total size of all pointers. chunk size that goes to shader
const wrenderStride = 4 * Float32Array.BYTES_PER_ELEMENT
@@ -207,12 +206,12 @@ export default (webgl: WebGL) => {
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
}
+ const updateCursorColor = (color: [number, number, number]) => {
+ webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
+ }
+
const updateCursorPosition = (row: number, col: number) => {
- webgl.gl.uniform2f(
- program.vars.cursorPosition,
- col,
- row,
- )
+ webgl.gl.uniform2f(program.vars.cursorPosition, col, row)
}
const updateColorAtlas = (colorAtlas: HTMLCanvasElement) => {
@@ -243,5 +242,14 @@ export default (webgl: WebGL) => {
webgl.gl.clear(webgl.gl.COLOR_BUFFER_BIT)
}
- return { clear, clearAll, render, resize, updateColorAtlas, updateCellSize, updateCursorPosition }
+ return {
+ clear,
+ clearAll,
+ render,
+ resize,
+ updateColorAtlas,
+ updateCellSize,
+ updateCursorPosition,
+ updateCursorColor,
+ }
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 7a4d30fc..8d82a992 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -31,6 +31,9 @@ const nutella = () => {
textFGRenderer.resize(width, height)
}
+ const updateCursorColor = (r: number, g: number, b: number) =>
+ textBGRenderer.updateCursorColor([r, g, b])
+
const updateCursorPosition = (row: number, col: number) =>
textBGRenderer.updateCursorPosition(row, col)
@@ -147,6 +150,7 @@ const nutella = () => {
updateFontAtlas,
updateColorAtlas,
updateCursorPosition,
+ updateCursorColor,
foregroundElement: foregroundGL.canvasElement,
backgroundElement: backgroundGL.canvasElement,
}
From 61667d401c571586a0ae54d5e5ac763c82355afc Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 10:08:16 -0600
Subject: [PATCH 04/26] Remove a bunch of stuff
---
src/components/text-input.tsx | 34 --------
src/core/input.ts | 154 +---------------------------------
src/windows/window.ts | 21 ++---
3 files changed, 12 insertions(+), 197 deletions(-)
diff --git a/src/components/text-input.tsx b/src/components/text-input.tsx
index 0f574b1f..df2803e4 100644
--- a/src/components/text-input.tsx
+++ b/src/components/text-input.tsx
@@ -1,6 +1,5 @@
import Loading from './loading'
import { paddingVH, cvar } from '../ui/css'
-import { xfrmUp } from '../core/input'
import { FormEvent } from 'inferno'
import Icon from './icon'
@@ -59,25 +58,6 @@ const nopMaybe = (obj: object) =>
get: (_, key) => Reflect.get(obj, key) || (() => {}),
}) as Props
-const keToStr = (e: KeyboardEvent) =>
- [
- e.key,
- (e.ctrlKey as any) | 0,
- (e.metaKey as any) | 0,
- (e.altKey as any) | 0,
- (e.shiftKey as any) | 0,
- ].join('')
-
-// TODO: could be better? it's global so will be shared between different
-// inputs. however only one input will have focus at a time, so perhaps
-// it's not a big deal
-//
-// the reason this has to live outside the function is because the view
-// function will be triggered on re-render. pressing keys will potentially
-// trigger re-renders, thus reseting the value of lastDown when inside
-// the function.
-let lastDown = ''
-
// TODO(smolck): But why though? Has to be another way to get access to
// `onComponentDidMount` with normal stuff like
const WhyInput = (props: any) =>
@@ -167,24 +147,10 @@ const textInput = (
setFocus(e.currentTarget, focus)
setPosition(e.currentTarget, position)
}}
- onKeyUp={(e: KeyboardEvent) => {
- const prevKeyAndThisOne = lastDown + keToStr(e)
-
- if (xfrmUp.has(prevKeyAndThisOne)) {
- const { key } = xfrmUp.get(prevKeyAndThisOne)!(e)
- if (key.toLowerCase() === '') {
- lastDown = ''
- ;(e.target as HTMLInputElement).blur()
- return $.hide()
- }
- }
- }}
onKeyDown={(e: KeyboardEvent) => {
const { ctrlKey: ctrl, metaKey: meta, key } = e
const cm = ctrl || meta
- lastDown = keToStr(e)
-
if (key === 'Tab') {
e.preventDefault()
return $.tab()
diff --git a/src/core/input.ts b/src/core/input.ts
index 5b480e48..d008aa3d 100644
--- a/src/core/input.ts
+++ b/src/core/input.ts
@@ -1,10 +1,8 @@
-import { normalizeVimMode } from '../support/neovim-utils'
import { input } from '../core/master-control'
import { VimMode } from '../neovim/types'
-import { $, is } from '../support/utils'
+import { $, } from '../support/utils'
import api from '../core/instance-api'
import { remote } from 'electron'
-import { Script } from 'vm'
export enum InputType {
Down = 'down',
@@ -20,21 +18,11 @@ interface KeyShape extends KeyboardEvent {
mode?: VimMode
}
-interface KeyTransform {
- mode: string
- event: 'hold' | 'up' | 'down'
- match: KeyboardEvent
- transform: string
-}
-
type OnKeyFn = (inputKeys: string, inputType: InputType) => void
const modifiers = ['Alt', 'Shift', 'Meta', 'Control']
const remaps = new Map()
let isCapturing = true
-let holding = ''
-let xformed = false
-let lastDown = ''
let windowHasFocus = true
let lastEscapeTimestamp = 0
let shouldClearEscapeOnNextAppFocus = false
@@ -93,94 +81,12 @@ const formatInput = $(combineModsWithKey, wrapKey)
const shortcuts = new Map()
const globalShortcuts = new Map void>()
-const resetInputState = () => {
- xformed = false
- lastDown = ''
- holding = ''
-}
-
export const focus = () => {
isCapturing = true
- resetInputState()
}
export const blur = () => {
isCapturing = false
- resetInputState()
-}
-
-export const setupRemapModifiers = (mappings: RemapModifer[]) => {
- if (!mappings) return
- remaps.clear()
- mappings.forEach((mapping) => remapModifier(mapping.from, mapping.to))
-}
-
-const vimscriptObjectToECMA = (obj: any) =>
- Object.entries(obj).reduce((res, [key, val]) => {
- if (val === 'true') Reflect.set(res, key, true)
- else if (val === 'false') Reflect.set(res, key, false)
- else Reflect.set(res, key, val)
- return res
- }, {})
-
-const setupTransforms = (transforms: KeyTransform[]) => {
- if (!transforms) return
- xfrmHold.clear()
- xfrmDown.clear()
- xfrmUp.clear()
-
- transforms.forEach(({ event, mode, match, transform }) => {
- const nvimMode = normalizeVimMode(mode)
- const fn = Reflect.get(addTransform, event)
- if (!fn) return console.error('can not add key-transform for event:', event)
-
- const transformFn = new Script(transform).runInThisContext()
- const matchObj =
- nvimMode !== VimMode.SomeModeThatIProbablyDontCareAbout
- ? Object.assign(vimscriptObjectToECMA(match), { mode: nvimMode })
- : vimscriptObjectToECMA(match)
-
- if (is.function(fn) && is.function(transformFn)) fn(matchObj, transformFn)
- })
-}
-
-const remapModifier = (from: string, to: string) => remaps.set(from, to)
-
-type Transformer = (input: KeyboardEvent) => KeyboardEvent
-export const xfrmHold = new Map()
-export const xfrmDown = new Map()
-export const xfrmUp = new Map()
-
-const keToStr = (e: KeyShape) =>
- [
- e.key,
- (e.ctrlKey) | 0,
- (e.metaKey) | 0,
- (e.altKey) | 0,
- (e.shiftKey) | 0,
- ].join('')
-
-const defkey = {
- ...new KeyboardEvent('keydown'),
- key: '',
- ctrlKey: false,
- metaKey: false,
- altKey: false,
- shiftKey: false,
-}
-
-const addTransform = {
- hold: (e: any, fn: Transformer) =>
- xfrmHold.set(keToStr({ ...defkey, ...e }), (e) => ({ ...e, ...fn(e) })),
-
- down: (e: any, fn: Transformer) =>
- xfrmDown.set(keToStr({ ...defkey, ...e }), (e) => ({ ...e, ...fn(e) })),
-
- up: (e: any, fn: Transformer) => {
- const before = keToStr({ ...defkey, ...e })
- const now = keToStr({ ...defkey, key: e.key })
- xfrmUp.set(before + now, (e) => ({ ...e, ...fn(e) }))
- },
}
export const stealInput = (onKeyFn: OnKeyFn) => {
@@ -244,54 +150,9 @@ const sendKeys = async (e: KeyboardEvent, inputType: InputType) => {
const keydownHandler = (e: KeyboardEvent) => {
if (!windowHasFocus || !isCapturing) return
- const es = keToStr(e)
- lastDown = es
-
- if (xfrmDown.has(es)) {
- const remapped = xfrmDown.get(holding)!(e)
- sendKeys(remapped, InputType.Down)
- return
- }
-
- if (xfrmHold.has(es)) {
- holding = es
- return
- }
-
- if (xfrmHold.has(holding)) {
- const remapped = xfrmHold.get(holding)!(e)
- sendKeys(remapped, InputType.Down)
- xformed = true
- return
- }
-
sendKeys(e, InputType.Down)
}
-const keyupHandler = (e: KeyboardEvent) => {
- if (!windowHasFocus || !isCapturing) return
-
- // one of the observed ways in which we can have a 'keyup' event without a
- // 'keydown' event is when the window receives focus while a key is already
- // pressed. this will happen with key combos like cmd+tab or alt+tab to
- // switch applications in mac/windows. there is probably no good reason to
- // send the keyup event key to neovim. in fact, this causes issues if we have
- // a xform mapping of cmd -> escape, as it sends an 'esc' key to neovim
- // terminal, thus swallowing the first key after app focus
- if (!lastDown) return
- const es = keToStr(e)
-
- const prevKeyAndThisOne = lastDown + es
- if (xfrmUp.has(prevKeyAndThisOne))
- return sendKeys(xfrmUp.get(prevKeyAndThisOne)!(e), InputType.Up)
-
- if (holding === es) {
- if (!xformed) sendKeys(e, InputType.Up)
- xformed = false
- holding = ''
- }
-}
-
// Need to handle key events from window for GUI elements like the external
// cmdline, so if the key composition textarea isn't focused (which it won't
// be when those elements are in use), handle the event from the window.
@@ -301,19 +162,10 @@ window.addEventListener('keydown', (e) => {
keydownHandler(e)
})
-// Same as above, just for `keyup` event.
-window.addEventListener('keyup', (e) => {
- if (textarea) if (textarea === document.activeElement) return
-
- keyupHandler(e)
-})
-
textarea?.addEventListener('keydown', keydownHandler)
-textarea?.addEventListener('keyup', keyupHandler)
remote.getCurrentWindow().on('focus', () => {
windowHasFocus = true
- resetInputState()
if (shouldClearEscapeOnNextAppFocus) {
// so if i remap 'cmd' down+up -> 'esc' and then hit cmd+tab to switch apps
// while in a terminal buffer, the application captures the 'cmd' (xform to
@@ -335,13 +187,9 @@ remote.getCurrentWindow().on('focus', () => {
remote.getCurrentWindow().on('blur', async () => {
windowHasFocus = false
- resetInputState()
const lastEscapeFromNow = Date.now() - lastEscapeTimestamp
const isTerminalMode = api.nvim.state.mode === VimMode.Terminal
const fixTermEscape = isTerminalMode && lastEscapeFromNow < 25
if (fixTermEscape) shouldClearEscapeOnNextAppFocus = true
})
-
-api.onConfig.inputRemapModifiersDidChange(setupRemapModifiers)
-api.onConfig.inputKeyTransformsDidChange(setupTransforms)
diff --git a/src/windows/window.ts b/src/windows/window.ts
index ecf9cf3f..188774e8 100644
--- a/src/windows/window.ts
+++ b/src/windows/window.ts
@@ -161,7 +161,7 @@ export default () => {
container.appendChild(nameplate.element)
container.appendChild(content)
- const dimensions = new WeakMap()
+ // const dimensions = new WeakMap()
const api = {
get id() {
@@ -280,15 +280,16 @@ export default () => {
}
api.refreshLayout = () => {
- let rect
- if (dimensions.has(content)) {
- rect = dimensions.get(content)
- }
- else {
- rect = content.getBoundingClientRect()
- dimensions.set(content, rect)
- }
- const { top, left, width, height } = rect
+ // TODO(smolck): This doesn't work with splits
+ // let rect
+ // if (dimensions.has(content)) {
+ // rect = dimensions.get(content)
+ // }
+ // else {
+ // rect = content.getBoundingClientRect()
+ // dimensions.set(content, rect)
+ // }
+ const { top, left, width, height } = content.getBoundingClientRect()
const x = left
const y = top - titleSpecs.height
From 8946efa1292ca94c6dbd7f773eb6ff5f87c5d9f9 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 10:59:13 -0600
Subject: [PATCH 05/26] More stuff to remove/change
---
src/core/input.ts | 13 +------------
src/core/instance-api.ts | 5 -----
2 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/src/core/input.ts b/src/core/input.ts
index d008aa3d..5d57ad29 100644
--- a/src/core/input.ts
+++ b/src/core/input.ts
@@ -9,19 +9,9 @@ export enum InputType {
Up = 'up',
}
-interface RemapModifer {
- from: string
- to: string
-}
-
-interface KeyShape extends KeyboardEvent {
- mode?: VimMode
-}
-
type OnKeyFn = (inputKeys: string, inputType: InputType) => void
const modifiers = ['Alt', 'Shift', 'Meta', 'Control']
-const remaps = new Map()
let isCapturing = true
let windowHasFocus = true
let lastEscapeTimestamp = 0
@@ -73,9 +63,8 @@ const wrapKey = (key: string): string =>
key.length > 1 && isUpper(key[0]) ? `<${key}>` : key
const combineModsWithKey = (mods: string, key: string) =>
mods.length ? `${mods}-${key}` : key
-const userModRemaps = (mods: string[]) => mods.map((m) => remaps.get(m) || m)
const joinModsWithDash = (mods: string[]) => mods.join('-')
-const mapMods = $(handleMods, userModRemaps, joinModsWithDash)
+const mapMods = $(handleMods, joinModsWithDash)
const mapKey = $(bypassEmptyMod, toVimKey)
const formatInput = $(combineModsWithKey, wrapKey)
const shortcuts = new Map()
diff --git a/src/core/instance-api.ts b/src/core/instance-api.ts
index 3bf1e045..d362ed8e 100644
--- a/src/core/instance-api.ts
+++ b/src/core/instance-api.ts
@@ -91,11 +91,6 @@ onSwitchVim(async () => {
ee.emit('git.status', gitInfo.status)
ee.emit('git.branch', gitInfo.branch)
ee.emit('nvim.load', true)
-
- const mappings = await instance.request.nvimGetVar('veonim_remap_modifiers')
- ee.emit('input.remap.modifiers', mappings)
- const transforms = await instance.request.nvimGetVar('veonim_key_transforms')
- ee.emit('input.key.transforms', transforms)
})
const getBufferInfo = (): Promise =>
From 6e5887e4ae511d0fb222caf26ea0cc69e8f61d25 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 12:26:39 -0600
Subject: [PATCH 06/26] CursorNormal -> Cursor
---
src/neovim/startup.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/neovim/startup.ts b/src/neovim/startup.ts
index a79c5de5..48fe9532 100644
--- a/src/neovim/startup.ts
+++ b/src/neovim/startup.ts
@@ -83,7 +83,7 @@ startup.defineFunc.UivonimCreateHighlights`
hi! link uvnFunction Function
hi! link uvnBuiltin Constant
hi! link uvnKeyword Keyword
- hi! link uvnCursor CursorNormal
+ hi! link uvnCursor Cursor
`
// autocmds in a separate function because chaining autocmds with "|" is bad
From efdbbdb7017610e02a1a4b0c7f275d8f542532d2 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 13:51:23 -0600
Subject: [PATCH 07/26] More cursor stuff
---
src/core/cursor.ts | 75 +++++------------------------------
src/render/redraw.ts | 2 -
src/render/webgl-text-bg.ts | 10 ++++-
src/render/webgl.ts | 3 ++
src/windows/window-manager.ts | 9 -----
5 files changed, 23 insertions(+), 76 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index a5d3665d..75820bc9 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -1,7 +1,4 @@
import * as windows from '../windows/window-manager'
-import { partialFill, translate } from '../ui/css'
-import { paddingX } from '../windows/window'
-import { cell } from '../core/workspace'
import { hexToRGB } from '../ui/css'
export enum CursorShape {
@@ -11,16 +8,12 @@ export enum CursorShape {
}
export const cursor = {
- row: 0,
- col: 0,
color: [0, 0, 0],
shape: CursorShape.block,
}
let cursorRequestedToBeHidden = false
let cursorEnabled = false
-let cursorCharVisible = false
-
// export const getCursorBoundingClientRect = () =>
// cursorline.getBoundingClientRect()
@@ -35,78 +28,32 @@ export const setCursorColor = (color: string) => {
b /= 255
cursor.color = [r, g, b]
- console.log('update cursor color', color, `rgb: ${r}, ${g}, ${b}`)
windows.webgl.updateCursorColor(r, g, b)
}
-export const enableCursor = () => (cursorEnabled = false)
-export const disableCursor = () => (cursorEnabled = false)
+export const enableCursor = () => (windows.webgl.enableCursor(true), cursorEnabled = true)
+export const disableCursor = () => (windows.webgl.enableCursor(false), cursorEnabled = false)
export const hideCursor = () => {
+ return
if (!cursorEnabled) return
- cursorRequestedToBeHidden = true
- // cursorEl.style.display = 'none'
- // cursorline.style.display = 'none'
+ console.log('hide cursor')
+ windows.webgl.enableCursor(false)
}
export const showCursor = () => {
+ return
if (!cursorEnabled) return
- cursorRequestedToBeHidden = false
- // cursorEl.style.display = 'flex'
- // cursorline.style.display = 'none'
-}
-
-export const showCursorline = () => (cursorline.style.display = '')
-
-export const updateCursorChar = () => {
- // cursorChar.innerText =
- // cursor.shape === CursorShape.block
- // ? windows.getActive().editor.getChar(cursor.row, cursor.col)
- // : ''
-
- // if (cursor.shape === CursorShape.block && !cursorCharVisible)
- // cursorChar.style.display = ''
-}
-
-const updateCursorCharInternal = (gridId: number, row: number, col: number) => {
- // if (cursor.shape !== CursorShape.block) {
- // cursorChar.style.display = 'none'
- // cursorCharVisible = false
- // cursorChar.innerText = ''
- // return
- // }
-
- // const char = windows.get(gridId).editor.getChar(row, col)
- // cursorChar.innerText = char
- // cursorChar.style.display = ''
- // cursorCharVisible = true
+ console.log('show cursor')
+ windows.webgl.enableCursor(true)
}
-export const moveCursor = (gridId: number, row: number, col: number) => {
- Object.assign(cursor, { row, col })
-
- // even if cursor(line) is hidden, we still need to update the positions.
- // once the cursor elements are re-activated, the position updated while
- // hidden must be accurate. (e.g. using jumpTo() in grep/references/etc)
- const win = windows.get(gridId)
- const cursorPos = win.positionToWorkspacePixels(row, col)
- const linePos = win.positionToWorkspacePixels(row, 0)
- const { width } = win.getWindowSize()
-
- // cursorEl.style.transform = translate(cursorPos.x, cursorPos.y)
-
- // Object.assign(cursorline.style, {
- // transform: translate(linePos.x - paddingX, linePos.y),
- // width: `${width}px`,
- // height: `${cell.height}px`,
- // })
-
- updateCursorCharInternal(gridId, row, col)
+// export const showCursorline = () => (cursorline.style.display = '')
- if (cursorRequestedToBeHidden) return
- showCursor()
+export const moveCursor = (row: number, col: number) => {
+ windows.webgl.updateCursorPosition(row, col)
}
setCursorShape(CursorShape.block)
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index 56650017..9a6f738d 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -10,7 +10,6 @@ import {
import {
hideCursor,
showCursor,
- updateCursorChar,
} from '../core/cursor'
import * as windows from '../windows/window-manager'
import * as dispatch from '../messaging/dispatch'
@@ -311,7 +310,6 @@ let layoutTimeout: NodeJS.Timeout | undefined
const refreshOrStartLayoutTimer = (winUpdates: boolean) => {
layoutTimeout = setTimeout(() => {
state_cursorVisible ? showCursor() : hideCursor()
- if (state_cursorVisible) updateCursorChar()
dispatch.pub('redraw')
if (!winUpdates) return
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index cbbc8bdd..086b273a 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -18,6 +18,7 @@ export default (webgl: WebGL) => {
cellSize: VarKind.Uniform,
cursorPosition: VarKind.Uniform,
cursorColor: VarKind.Uniform,
+ cursorEnabled: VarKind.Uniform,
})
program.setVertexShader(
@@ -30,6 +31,7 @@ export default (webgl: WebGL) => {
uniform vec2 ${v.colorAtlasResolution};
uniform vec2 ${v.cellSize};
uniform vec4 ${v.cursorColor};
+ uniform bool ${v.cursorEnabled};
uniform float ${v.hlidType};
uniform sampler2D ${v.colorAtlasTextureId};
@@ -49,7 +51,7 @@ export default (webgl: WebGL) => {
float color_y = ${v.hlidType} * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- if (${v.cursorPosition} == ${v.cellPosition}) {
+ if (${v.cursorPosition} == ${v.cellPosition} && ${v.cursorEnabled}) {
o_color = cursorColor;
} else {
vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
@@ -87,6 +89,8 @@ export default (webgl: WebGL) => {
)
webgl.gl.uniform2f(program.vars.cursorPosition, 0, 0)
webgl.gl.uniform4fv(program.vars.cursorColor, [0, 0, 0, 1])
+ // @ts-ignore
+ webgl.gl.uniform1i(program.vars.cursorEnabled, true)
// total size of all pointers. chunk size that goes to shader
const wrenderStride = 4 * Float32Array.BYTES_PER_ELEMENT
@@ -206,6 +210,9 @@ export default (webgl: WebGL) => {
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
}
+ // @ts-ignore
+ const enableCursor = (enable: boolean) => webgl.gl.uniform1i(program.vars.cursorEnabled, enable)
+
const updateCursorColor = (color: [number, number, number]) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
}
@@ -249,6 +256,7 @@ export default (webgl: WebGL) => {
resize,
updateColorAtlas,
updateCellSize,
+ enableCursor,
updateCursorPosition,
updateCursorColor,
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 8d82a992..0db3bf09 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -31,6 +31,8 @@ const nutella = () => {
textFGRenderer.resize(width, height)
}
+ const enableCursor = (enable: boolean) => textBGRenderer.enableCursor(enable)
+
const updateCursorColor = (r: number, g: number, b: number) =>
textBGRenderer.updateCursorColor([r, g, b])
@@ -151,6 +153,7 @@ const nutella = () => {
updateColorAtlas,
updateCursorPosition,
updateCursorColor,
+ enableCursor,
foregroundElement: foregroundGL.canvasElement,
backgroundElement: backgroundGL.canvasElement,
}
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index bb7f3c44..d9bfdb00 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -205,15 +205,6 @@ export const layout = () => {
// wait for flex grid styles to be applied to all windows and trigger dom layout
windowGridInfo.forEach(({ gridId }) => windows.get(gridId)!.refreshLayout())
refreshWebGLGrid()
-
- // cursorline width does not always get resized correctly after window
- // layout changes, so we will force an update of the cursor to make sure
- // it is correct. test case: two vert splits, move to left and :bo
- state.activeGrid &&
- requestAnimationFrame(() => {
- if (!windows.has(state.activeGrid)) return
- moveCursor(state.activeInstanceGrid, cursor.row, cursor.col)
- })
}
const updateWindowNameplates = () =>
From 8eff4a4406bd406c3ce3cf3f0ecaf78b4454ccaa Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 19:34:43 -0600
Subject: [PATCH 08/26] More cursor stuff
---
src/core/cursor.ts | 18 ++++++++----------
src/render/webgl-text-bg.ts | 14 +++++++-------
src/render/webgl.ts | 4 ++--
3 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index 75820bc9..de1bdc84 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -8,14 +8,15 @@ export enum CursorShape {
}
export const cursor = {
+ row: 0,
+ col: 0,
color: [0, 0, 0],
shape: CursorShape.block,
}
-let cursorRequestedToBeHidden = false
let cursorEnabled = false
// export const getCursorBoundingClientRect = () =>
- // cursorline.getBoundingClientRect()
+// cursorline.getBoundingClientRect()
export const setCursorShape = (shape: CursorShape) => {
cursor.shape = shape
@@ -31,28 +32,25 @@ export const setCursorColor = (color: string) => {
windows.webgl.updateCursorColor(r, g, b)
}
-export const enableCursor = () => (windows.webgl.enableCursor(true), cursorEnabled = true)
-export const disableCursor = () => (windows.webgl.enableCursor(false), cursorEnabled = false)
+export const enableCursor = () => (cursorEnabled = true)
+export const disableCursor = () => (cursorEnabled = false)
export const hideCursor = () => {
- return
if (!cursorEnabled) return
- console.log('hide cursor')
- windows.webgl.enableCursor(false)
+ windows.webgl.showCursor(false)
}
export const showCursor = () => {
- return
if (!cursorEnabled) return
- console.log('show cursor')
- windows.webgl.enableCursor(true)
+ windows.webgl.showCursor(true)
}
// export const showCursorline = () => (cursorline.style.display = '')
export const moveCursor = (row: number, col: number) => {
+ Object.assign(cursor, { row, col })
windows.webgl.updateCursorPosition(row, col)
}
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 086b273a..4dae2d14 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -18,7 +18,7 @@ export default (webgl: WebGL) => {
cellSize: VarKind.Uniform,
cursorPosition: VarKind.Uniform,
cursorColor: VarKind.Uniform,
- cursorEnabled: VarKind.Uniform,
+ shouldShowCursor: VarKind.Uniform,
})
program.setVertexShader(
@@ -31,7 +31,7 @@ export default (webgl: WebGL) => {
uniform vec2 ${v.colorAtlasResolution};
uniform vec2 ${v.cellSize};
uniform vec4 ${v.cursorColor};
- uniform bool ${v.cursorEnabled};
+ uniform bool ${v.shouldShowCursor};
uniform float ${v.hlidType};
uniform sampler2D ${v.colorAtlasTextureId};
@@ -51,7 +51,7 @@ export default (webgl: WebGL) => {
float color_y = ${v.hlidType} * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- if (${v.cursorPosition} == ${v.cellPosition} && ${v.cursorEnabled}) {
+ if (${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor}) {
o_color = cursorColor;
} else {
vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
@@ -90,7 +90,7 @@ export default (webgl: WebGL) => {
webgl.gl.uniform2f(program.vars.cursorPosition, 0, 0)
webgl.gl.uniform4fv(program.vars.cursorColor, [0, 0, 0, 1])
// @ts-ignore
- webgl.gl.uniform1i(program.vars.cursorEnabled, true)
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, true)
// total size of all pointers. chunk size that goes to shader
const wrenderStride = 4 * Float32Array.BYTES_PER_ELEMENT
@@ -194,7 +194,7 @@ export default (webgl: WebGL) => {
x: number,
y: number,
width: number,
- height: number
+ height: number,
) => {
readjustViewportMaybe(x, y, width, height)
wrenderBuffer.setData(buffer)
@@ -211,7 +211,7 @@ export default (webgl: WebGL) => {
}
// @ts-ignore
- const enableCursor = (enable: boolean) => webgl.gl.uniform1i(program.vars.cursorEnabled, enable)
+ const showCursor = (enable: boolean) => webgl.gl.uniform1i(program.vars.shouldShowCursor, enable)
const updateCursorColor = (color: [number, number, number]) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
@@ -256,7 +256,7 @@ export default (webgl: WebGL) => {
resize,
updateColorAtlas,
updateCellSize,
- enableCursor,
+ showCursor,
updateCursorPosition,
updateCursorColor,
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 0db3bf09..c0d36544 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -31,7 +31,7 @@ const nutella = () => {
textFGRenderer.resize(width, height)
}
- const enableCursor = (enable: boolean) => textBGRenderer.enableCursor(enable)
+ const showCursor = (enable: boolean) => textBGRenderer.showCursor(enable)
const updateCursorColor = (r: number, g: number, b: number) =>
textBGRenderer.updateCursorColor([r, g, b])
@@ -153,7 +153,7 @@ const nutella = () => {
updateColorAtlas,
updateCursorPosition,
updateCursorColor,
- enableCursor,
+ showCursor,
foregroundElement: foregroundGL.canvasElement,
backgroundElement: backgroundGL.canvasElement,
}
From b37777905a280f1578f10001e3ee14f5e008d559 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 19:43:13 -0600
Subject: [PATCH 09/26] prettier
---
src/bootstrap/galaxy.ts | 5 ++++-
src/core/input.ts | 2 +-
src/render/redraw.ts | 5 +----
src/render/webgl-text-bg.ts | 5 +++--
src/windows/window-manager.ts | 5 ++---
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/bootstrap/galaxy.ts b/src/bootstrap/galaxy.ts
index 59cde13c..9303150e 100644
--- a/src/bootstrap/galaxy.ts
+++ b/src/bootstrap/galaxy.ts
@@ -88,4 +88,7 @@ dispatch.sub('window.change', () => {
})
// TODO(smolck): Put this somewhere else?
-api.onAction('update-nameplates', () => (windows.refresh(), console.log('refresh')))
+api.onAction(
+ 'update-nameplates',
+ () => (windows.refresh(), console.log('refresh'))
+)
diff --git a/src/core/input.ts b/src/core/input.ts
index 5d57ad29..8cebe9d5 100644
--- a/src/core/input.ts
+++ b/src/core/input.ts
@@ -1,6 +1,6 @@
import { input } from '../core/master-control'
import { VimMode } from '../neovim/types'
-import { $, } from '../support/utils'
+import { $ } from '../support/utils'
import api from '../core/instance-api'
import { remote } from 'electron'
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index 9a6f738d..747e0402 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -7,10 +7,7 @@ import {
getCharIndex,
getUpdatedFontAtlasMaybe,
} from '../render/font-texture-atlas'
-import {
- hideCursor,
- showCursor,
-} from '../core/cursor'
+import { hideCursor, showCursor } from '../core/cursor'
import * as windows from '../windows/window-manager'
import * as dispatch from '../messaging/dispatch'
import { onRedraw, resizeGrid } from '../core/master-control'
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 4dae2d14..51024861 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -194,7 +194,7 @@ export default (webgl: WebGL) => {
x: number,
y: number,
width: number,
- height: number,
+ height: number
) => {
readjustViewportMaybe(x, y, width, height)
wrenderBuffer.setData(buffer)
@@ -211,7 +211,8 @@ export default (webgl: WebGL) => {
}
// @ts-ignore
- const showCursor = (enable: boolean) => webgl.gl.uniform1i(program.vars.shouldShowCursor, enable)
+ const showCursor = (enable: boolean) =>
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, enable)
const updateCursorColor = (color: [number, number, number]) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index d9bfdb00..b5c6862e 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -32,11 +32,10 @@ const getWindowById = (windowId: number) => {
const getInstanceWindows = (id = instances.current) =>
[...windows.values()].filter((win) => win.id.startsWith(`i${id}`))
-let webglTimeout: NodeJS.Timeout | undefined;
+let webglTimeout: NodeJS.Timeout | undefined
const refreshWebGLGrid = () => {
- if (webglTimeout)
- clearTimeout(webglTimeout)
+ if (webglTimeout) clearTimeout(webglTimeout)
webglTimeout = setTimeout(refreshWebGLGridImplementation, 15)
}
From f1a3e6224983f5b561afc659c3a76090cb39c141 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 21:36:49 -0600
Subject: [PATCH 10/26] Remove layout timeout change (to be done in another PR)
---
src/render/redraw.ts | 23 +++++++----------------
src/windows/window.ts | 11 -----------
2 files changed, 7 insertions(+), 27 deletions(-)
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index 747e0402..caf349f0 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -302,19 +302,6 @@ const win_float_pos = (e: any) => {
}
}
-let layoutTimeout: NodeJS.Timeout | undefined
-
-const refreshOrStartLayoutTimer = (winUpdates: boolean) => {
- layoutTimeout = setTimeout(() => {
- state_cursorVisible ? showCursor() : hideCursor()
- dispatch.pub('redraw')
- if (!winUpdates) return
-
- windows.disposeInvalidWindows()
- windows.layout()
- }, 10)
-}
-
onRedraw((redrawEvents) => {
// because of circular logic/infinite loop. cmdline_show updates UI, UI makes
// a change in the cmdline, nvim sends redraw again. we cut that stuff out
@@ -325,7 +312,6 @@ onRedraw((redrawEvents) => {
const messageEvents: any = []
const eventCount = redrawEvents.length
-
for (let ix = 0; ix < eventCount; ix++) {
const ev = redrawEvents[ix]
const e = ev[0]
@@ -382,6 +368,11 @@ onRedraw((redrawEvents) => {
renderEvents.messageClearPromptsMaybeHack(state_cursorVisible)
- if (!layoutTimeout) refreshOrStartLayoutTimer(winUpdates)
- else clearTimeout(layoutTimeout), refreshOrStartLayoutTimer(winUpdates)
+ requestAnimationFrame(() => {
+ state_cursorVisible ? showCursor() : hideCursor()
+ dispatch.pub('redraw')
+ if (!winUpdates) return
+ windows.disposeInvalidWindows()
+ windows.layout()
+ })
})
diff --git a/src/windows/window.ts b/src/windows/window.ts
index 188774e8..0649a1d2 100644
--- a/src/windows/window.ts
+++ b/src/windows/window.ts
@@ -161,8 +161,6 @@ export default () => {
container.appendChild(nameplate.element)
container.appendChild(content)
- // const dimensions = new WeakMap()
-
const api = {
get id() {
return wininfo.id
@@ -280,15 +278,6 @@ export default () => {
}
api.refreshLayout = () => {
- // TODO(smolck): This doesn't work with splits
- // let rect
- // if (dimensions.has(content)) {
- // rect = dimensions.get(content)
- // }
- // else {
- // rect = content.getBoundingClientRect()
- // dimensions.set(content, rect)
- // }
const { top, left, width, height } = content.getBoundingClientRect()
const x = left
From 49da5892298ecc68686c5ce7257e21616daf3398 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 1 Nov 2020 21:43:46 -0600
Subject: [PATCH 11/26] Remove rest of timeout code
---
src/windows/window-manager.ts | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index b5c6862e..13260acb 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -32,15 +32,7 @@ const getWindowById = (windowId: number) => {
const getInstanceWindows = (id = instances.current) =>
[...windows.values()].filter((win) => win.id.startsWith(`i${id}`))
-let webglTimeout: NodeJS.Timeout | undefined
-
const refreshWebGLGrid = () => {
- if (webglTimeout) clearTimeout(webglTimeout)
- webglTimeout = setTimeout(refreshWebGLGridImplementation, 15)
-}
-
-const refreshWebGLGridImplementation = () => {
- webglTimeout = undefined
webgl.clearAll()
getInstanceWindows().forEach((w) => w.redrawFromGridBuffer())
}
From 211efed0911e7b4a9a19d13d4f17bc6df9138734 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 5 Nov 2020 07:21:25 -0600
Subject: [PATCH 12/26] Initial cursor line implementation
---
src/core/cursor.ts | 10 ++++++----
src/render/webgl-text-bg.ts | 20 ++++++++++++++++++--
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index de1bdc84..09a041c7 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -2,9 +2,9 @@ import * as windows from '../windows/window-manager'
import { hexToRGB } from '../ui/css'
export enum CursorShape {
- block,
- line,
- underline,
+ block = 0,
+ line = 1,
+ underline = 2,
}
export const cursor = {
@@ -12,14 +12,16 @@ export const cursor = {
col: 0,
color: [0, 0, 0],
shape: CursorShape.block,
+ size: 20,
}
let cursorEnabled = false
// export const getCursorBoundingClientRect = () =>
// cursorline.getBoundingClientRect()
-export const setCursorShape = (shape: CursorShape) => {
+export const setCursorShape = (shape: CursorShape, size = 20) => {
cursor.shape = shape
+ cursor.size = size;
}
export const setCursorColor = (color: string) => {
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 51024861..5ed305c6 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -18,6 +18,7 @@ export default (webgl: WebGL) => {
cellSize: VarKind.Uniform,
cursorPosition: VarKind.Uniform,
cursorColor: VarKind.Uniform,
+ cursorShape: VarKind.Uniform,
shouldShowCursor: VarKind.Uniform,
})
@@ -32,6 +33,7 @@ export default (webgl: WebGL) => {
uniform vec2 ${v.cellSize};
uniform vec4 ${v.cursorColor};
uniform bool ${v.shouldShowCursor};
+ uniform int ${v.cursorShape};
uniform float ${v.hlidType};
uniform sampler2D ${v.colorAtlasTextureId};
@@ -39,8 +41,15 @@ export default (webgl: WebGL) => {
out vec2 o_colorPosition;
void main() {
+ bool isCursorCell = ${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor};
vec2 absolutePixelPosition = ${v.cellPosition} * ${v.cellSize};
- vec2 vertexPosition = absolutePixelPosition + ${v.quadVertex};
+ vec2 vertexPosition;
+ if (${v.cursorShape} == 1 && isCursorCell) {
+ vertexPosition =
+ absolutePixelPosition + vec2(${v.quadVertex}.x / 2.0, ${v.quadVertex}.y);
+ } else {
+ vertexPosition = absolutePixelPosition + ${v.quadVertex};
+ }
vec2 posFloat = vertexPosition / ${v.canvasResolution};
float posx = posFloat.x * 2.0 - 1.0;
float posy = posFloat.y * -2.0 + 1.0;
@@ -51,7 +60,7 @@ export default (webgl: WebGL) => {
float color_y = ${v.hlidType} * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- if (${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor}) {
+ if (isCursorCell) {
o_color = cursorColor;
} else {
vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
@@ -118,6 +127,7 @@ export default (webgl: WebGL) => {
pointer: program.vars.quadVertex,
type: webgl.gl.FLOAT,
size: 2,
+ offset: 0,
})
const updateCellSize = (initial = false) => {
@@ -125,14 +135,19 @@ export default (webgl: WebGL) => {
boxes: new Float32Array([
0,
0,
+
cell.width,
cell.height,
+
0,
cell.height,
+
cell.width,
0,
+
cell.width,
cell.height,
+
0,
0,
]),
@@ -219,6 +234,7 @@ export default (webgl: WebGL) => {
}
const updateCursorPosition = (row: number, col: number) => {
+ webgl.gl.uniform1i(program.vars.cursorShape, cursor.shape)
webgl.gl.uniform2f(program.vars.cursorPosition, col, row)
}
From a5ef81448529f138b874ea1b9f0e6f18b2cc56ed Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 5 Nov 2020 10:06:09 -0600
Subject: [PATCH 13/26] Make the cursor line shape much smaller
---
src/render/webgl-text-bg.ts | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 5ed305c6..7cb9b368 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -36,17 +36,17 @@ export default (webgl: WebGL) => {
uniform int ${v.cursorShape};
uniform float ${v.hlidType};
uniform sampler2D ${v.colorAtlasTextureId};
-
out vec4 o_color;
out vec2 o_colorPosition;
void main() {
bool isCursorCell = ${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor};
+
vec2 absolutePixelPosition = ${v.cellPosition} * ${v.cellSize};
vec2 vertexPosition;
if (${v.cursorShape} == 1 && isCursorCell) {
vertexPosition =
- absolutePixelPosition + vec2(${v.quadVertex}.x / 2.0, ${v.quadVertex}.y);
+ absolutePixelPosition + vec2(${v.quadVertex}.x / 8.0, ${v.quadVertex}.y);
} else {
vertexPosition = absolutePixelPosition + ${v.quadVertex};
}
@@ -135,19 +135,14 @@ export default (webgl: WebGL) => {
boxes: new Float32Array([
0,
0,
-
cell.width,
cell.height,
-
0,
cell.height,
-
cell.width,
0,
-
cell.width,
cell.height,
-
0,
0,
]),
From 4ff4c6f7a8c70b2023dfdc062a394c93a54695aa Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 5 Nov 2020 15:47:06 -0600
Subject: [PATCH 14/26] Render the line shape for the cursor
---
src/render/webgl-text-bg.ts | 87 +++++++++++++++++++++++++------------
1 file changed, 60 insertions(+), 27 deletions(-)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 7cb9b368..22c2efed 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -9,6 +9,7 @@ export default (webgl: WebGL) => {
const program = webgl.setupProgram({
quadVertex: VarKind.Attribute,
+ isCursorTri: VarKind.Attribute,
cellPosition: VarKind.Attribute,
hlid: VarKind.Attribute,
hlidType: VarKind.Uniform,
@@ -26,6 +27,7 @@ export default (webgl: WebGL) => {
(v) => `#version 300 es
in vec2 ${v.quadVertex};
in vec2 ${v.cellPosition};
+ in float ${v.isCursorTri};
in float ${v.hlid};
uniform vec2 ${v.cursorPosition};
uniform vec2 ${v.canvasResolution};
@@ -43,13 +45,7 @@ export default (webgl: WebGL) => {
bool isCursorCell = ${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor};
vec2 absolutePixelPosition = ${v.cellPosition} * ${v.cellSize};
- vec2 vertexPosition;
- if (${v.cursorShape} == 1 && isCursorCell) {
- vertexPosition =
- absolutePixelPosition + vec2(${v.quadVertex}.x / 8.0, ${v.quadVertex}.y);
- } else {
- vertexPosition = absolutePixelPosition + ${v.quadVertex};
- }
+ vec2 vertexPosition = absolutePixelPosition + ${v.quadVertex};
vec2 posFloat = vertexPosition / ${v.canvasResolution};
float posx = posFloat.x * 2.0 - 1.0;
float posy = posFloat.y * -2.0 + 1.0;
@@ -60,7 +56,19 @@ export default (webgl: WebGL) => {
float color_y = ${v.hlidType} * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- if (isCursorCell) {
+ bool condition;
+ ${/*
+ TODO(smolck): I'm almost certain there's a way to do this
+ condition all in one without extra if statements, but my brain is
+ not finding it right now.
+ */''}
+ if (${v.cursorShape} == 1) {
+ condition = isCursorCell && isCursorTri == 1.0;
+ } else {
+ condition = isCursorCell;
+ }
+
+ if (condition) {
o_color = cursorColor;
} else {
vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
@@ -123,28 +131,53 @@ export default (webgl: WebGL) => {
},
])
- const quadBuffer = program.setupData({
- pointer: program.vars.quadVertex,
- type: webgl.gl.FLOAT,
- size: 2,
- offset: 0,
- })
+ console.log(Float32Array.BYTES_PER_ELEMENT)
+ const quadBuffer = program.setupData([
+ {
+ pointer: program.vars.quadVertex,
+ type: webgl.gl.FLOAT,
+ size: 2,
+ offset: 0,
+ },
+ {
+ pointer: program.vars.isCursorTri,
+ type: webgl.gl.FLOAT,
+ size: 1,
+ offset: Float32Array.BYTES_PER_ELEMENT * 2 * 12
+ }
+ ])
const updateCellSize = (initial = false) => {
+ const w = cell.width
+ const h = cell.height
+ const w6th = w / 6
+
const next = {
boxes: new Float32Array([
- 0,
- 0,
- cell.width,
- cell.height,
- 0,
- cell.height,
- cell.width,
- 0,
- cell.width,
- cell.height,
- 0,
- 0,
+ 0, 0,
+ w6th, h,
+ 0, h,
+
+ w6th, 0,
+ w6th, h,
+ 0, 0,
+
+ w6th, 0,
+ w, h,
+ w6th, h,
+
+ w, 0,
+ w, h,
+ w6th, 0,
+
+ // TODO(smolck): More compact way of doing this. Also, note that the 1's
+ // specify which triangles of the above to color in for the cursor, and the zeroes
+ // which triangles not to color in, *if* the cursor is a line shape. If
+ // it isn't a line shape (atm a block shape), these are ignored.
+ 1, 1, 1,
+ 1, 1, 1,
+ 0, 0, 0,
+ 0, 0, 0,
]),
lines: new Float32Array([
0,
@@ -212,7 +245,7 @@ export default (webgl: WebGL) => {
// background
quadBuffer.setData(quads.boxes)
webgl.gl.uniform1f(program.vars.hlidType, 0)
- webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
+ webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 12, buffer.length / 4)
// underlines
quadBuffer.setData(quads.lines)
From d2d69c30a9ce01e994d30417b924efd04d974f22 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 5 Nov 2020 15:49:26 -0600
Subject: [PATCH 15/26] Remove console.log
---
src/render/webgl-text-bg.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 22c2efed..dcc4ba69 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -131,7 +131,6 @@ export default (webgl: WebGL) => {
},
])
- console.log(Float32Array.BYTES_PER_ELEMENT)
const quadBuffer = program.setupData([
{
pointer: program.vars.quadVertex,
From f6f9590cd65a5a6f052d06278ea760ea21b2fd73 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sun, 8 Nov 2020 22:32:01 -0600
Subject: [PATCH 16/26] "Fix" the underline issue
---
src/render/webgl-text-bg.ts | 87 +++++++++++++++++++++++++----------
src/windows/window-manager.ts | 1 -
2 files changed, 63 insertions(+), 25 deletions(-)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index dcc4ba69..918f9600 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -6,6 +6,7 @@ import { cursor } from '../core/cursor'
export default (webgl: WebGL) => {
const viewport = { x: 0, y: 0, width: 0, height: 0 }
+ let shouldShowCursor = true
const program = webgl.setupProgram({
quadVertex: VarKind.Attribute,
@@ -42,7 +43,9 @@ export default (webgl: WebGL) => {
out vec2 o_colorPosition;
void main() {
- bool isCursorCell = ${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor};
+ bool isCursorCell = ${v.cursorPosition} == ${v.cellPosition} && ${
+ v.shouldShowCursor
+ };
vec2 absolutePixelPosition = ${v.cellPosition} * ${v.cellSize};
vec2 vertexPosition = absolutePixelPosition + ${v.quadVertex};
@@ -57,11 +60,13 @@ export default (webgl: WebGL) => {
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
bool condition;
- ${/*
+ ${
+ /*
TODO(smolck): I'm almost certain there's a way to do this
condition all in one without extra if statements, but my brain is
not finding it right now.
- */''}
+ */ ''
+ }
if (${v.cursorShape} == 1) {
condition = isCursorCell && isCursorTri == 1.0;
} else {
@@ -107,7 +112,7 @@ export default (webgl: WebGL) => {
webgl.gl.uniform2f(program.vars.cursorPosition, 0, 0)
webgl.gl.uniform4fv(program.vars.cursorColor, [0, 0, 0, 1])
// @ts-ignore
- webgl.gl.uniform1i(program.vars.shouldShowCursor, true)
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor)
// total size of all pointers. chunk size that goes to shader
const wrenderStride = 4 * Float32Array.BYTES_PER_ELEMENT
@@ -142,8 +147,8 @@ export default (webgl: WebGL) => {
pointer: program.vars.isCursorTri,
type: webgl.gl.FLOAT,
size: 1,
- offset: Float32Array.BYTES_PER_ELEMENT * 2 * 12
- }
+ offset: Float32Array.BYTES_PER_ELEMENT * 2 * 12,
+ },
])
const updateCellSize = (initial = false) => {
@@ -153,30 +158,50 @@ export default (webgl: WebGL) => {
const next = {
boxes: new Float32Array([
- 0, 0,
- w6th, h,
- 0, h,
+ 0,
+ 0,
+ w6th,
+ h,
+ 0,
+ h,
- w6th, 0,
- w6th, h,
- 0, 0,
+ w6th,
+ 0,
+ w6th,
+ h,
+ 0,
+ 0,
- w6th, 0,
- w, h,
- w6th, h,
+ w6th,
+ 0,
+ w,
+ h,
+ w6th,
+ h,
- w, 0,
- w, h,
- w6th, 0,
+ w,
+ 0,
+ w,
+ h,
+ w6th,
+ 0,
// TODO(smolck): More compact way of doing this. Also, note that the 1's
// specify which triangles of the above to color in for the cursor, and the zeroes
// which triangles not to color in, *if* the cursor is a line shape. If
// it isn't a line shape (atm a block shape), these are ignored.
- 1, 1, 1,
- 1, 1, 1,
- 0, 0, 0,
- 0, 0, 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
]),
lines: new Float32Array([
0,
@@ -191,6 +216,13 @@ export default (webgl: WebGL) => {
cell.height,
0,
cell.height - 1,
+
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
]),
}
@@ -248,13 +280,20 @@ export default (webgl: WebGL) => {
// underlines
quadBuffer.setData(quads.lines)
+
+ // @ts-ignore TODO(smolck): HACKS
+ if (shouldShowCursor) webgl.gl.uniform1i(program.vars.shouldShowCursor, false)
+
webgl.gl.uniform1f(program.vars.hlidType, 2)
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
+
+ // @ts-ignore TODO(smolck): HACKS
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor)
}
- // @ts-ignore
const showCursor = (enable: boolean) =>
- webgl.gl.uniform1i(program.vars.shouldShowCursor, enable)
+ // @ts-ignore
+ (shouldShowCursor = enable, webgl.gl.uniform1i(program.vars.shouldShowCursor, enable))
const updateCursorColor = (color: [number, number, number]) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index 13260acb..f1810d80 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -1,7 +1,6 @@
import { generateColorLookupAtlas } from '../render/highlight-attributes'
import { onSwitchVim, instances } from '../core/instance-manager'
import CreateWindow, { Window, paddingX } from '../windows/window'
-import { cursor, moveCursor } from '../core/cursor'
import CreateWebGLRenderer from '../render/webgl'
import { onElementResize } from '../ui/vanilla'
import * as workspace from '../core/workspace'
From b0ba912f6b97e669f2cf6b0a593b804867728079 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Wed, 11 Nov 2020 12:30:28 -0600
Subject: [PATCH 17/26] Fix cursor shape not changing on insert
also add some code back that I removed, use `moveCursor` instead
of `windows.webgl.updateCursorPosition` directly in `grid_cursor_goto`,
and maybe some other things
---
src/core/cursor.ts | 7 +++++++
src/render/redraw.ts | 4 ++--
src/render/webgl-text-bg.ts | 8 ++++++--
src/render/webgl.ts | 4 ++++
src/windows/window-manager.ts | 11 +++++++++++
5 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index 09a041c7..ad8e8f18 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -16,12 +16,14 @@ export const cursor = {
}
let cursorEnabled = false
+let cursorRequestedToBeHidden = false
// export const getCursorBoundingClientRect = () =>
// cursorline.getBoundingClientRect()
export const setCursorShape = (shape: CursorShape, size = 20) => {
cursor.shape = shape
cursor.size = size;
+ windows.webgl.updateCursorShape(shape)
}
export const setCursorColor = (color: string) => {
@@ -39,12 +41,14 @@ export const disableCursor = () => (cursorEnabled = false)
export const hideCursor = () => {
if (!cursorEnabled) return
+ cursorRequestedToBeHidden = true
windows.webgl.showCursor(false)
}
export const showCursor = () => {
if (!cursorEnabled) return
+ cursorRequestedToBeHidden = false
windows.webgl.showCursor(true)
}
@@ -53,6 +57,9 @@ export const showCursor = () => {
export const moveCursor = (row: number, col: number) => {
Object.assign(cursor, { row, col })
+
+ if (cursorRequestedToBeHidden) return
+ showCursor()
windows.webgl.updateCursorPosition(row, col)
}
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index 78ebb735..ac2f4e0c 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -7,7 +7,7 @@ import {
getCharIndex,
getUpdatedFontAtlasMaybe,
} from '../render/font-texture-atlas'
-import { hideCursor, showCursor } from '../core/cursor'
+import { hideCursor, showCursor, moveCursor } from '../core/cursor'
import * as windows from '../windows/window-manager'
import * as dispatch from '../messaging/dispatch'
import { onRedraw, resizeGrid } from '../core/master-control'
@@ -87,7 +87,7 @@ const grid_cursor_goto = ([, [gridId, row, col]]: any) => {
state_cursorVisible = gridId !== 1
if (gridId === 1) return
windows.setActiveGrid(gridId)
- windows.webgl.updateCursorPosition(row, col)
+ moveCursor(row, col)
}
const grid_scroll = ([
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 918f9600..704e52ef 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -2,7 +2,7 @@ import { getColorAtlas, colors } from '../render/highlight-attributes'
import { WebGL, VarKind } from '../render/webgl-utils'
import { cell } from '../core/workspace'
import { hexToRGB } from '../ui/css'
-import { cursor } from '../core/cursor'
+import { CursorShape } from '../core/cursor'
export default (webgl: WebGL) => {
const viewport = { x: 0, y: 0, width: 0, height: 0 }
@@ -299,8 +299,11 @@ export default (webgl: WebGL) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
}
+ const updateCursorShape = (shape: CursorShape) => {
+ webgl.gl.uniform1i(program.vars.cursorShape, shape)
+ }
+
const updateCursorPosition = (row: number, col: number) => {
- webgl.gl.uniform1i(program.vars.cursorShape, cursor.shape)
webgl.gl.uniform2f(program.vars.cursorPosition, col, row)
}
@@ -341,6 +344,7 @@ export default (webgl: WebGL) => {
updateCellSize,
showCursor,
updateCursorPosition,
+ updateCursorShape,
updateCursorColor,
}
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index c0d36544..8152ce14 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -3,6 +3,7 @@ import CreateWebGL from '../render/webgl-utils'
import { cell } from '../core/workspace'
import TextFG from '../render/webgl-text-fg'
import TextBG from '../render/webgl-text-bg'
+import { CursorShape } from '../core/cursor'
export interface WebGLView {
resize: (rows: number, cols: number) => void
@@ -33,6 +34,8 @@ const nutella = () => {
const showCursor = (enable: boolean) => textBGRenderer.showCursor(enable)
+ const updateCursorShape = (shape: CursorShape) => textBGRenderer.updateCursorShape(shape)
+
const updateCursorColor = (r: number, g: number, b: number) =>
textBGRenderer.updateCursorColor([r, g, b])
@@ -151,6 +154,7 @@ const nutella = () => {
updateCellSize,
updateFontAtlas,
updateColorAtlas,
+ updateCursorShape,
updateCursorPosition,
updateCursorColor,
showCursor,
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index f1810d80..d6a25ed2 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -1,6 +1,7 @@
import { generateColorLookupAtlas } from '../render/highlight-attributes'
import { onSwitchVim, instances } from '../core/instance-manager'
import CreateWindow, { Window, paddingX } from '../windows/window'
+import { cursor, moveCursor } from '../core/cursor'
import CreateWebGLRenderer from '../render/webgl'
import { onElementResize } from '../ui/vanilla'
import * as workspace from '../core/workspace'
@@ -8,6 +9,7 @@ import { throttle } from '../support/utils'
import windowSizer from '../windows/sizer'
import api from '../core/instance-api'
+
export const size = { width: 0, height: 0 }
export const webgl = CreateWebGLRenderer()
const windows = new Map()
@@ -195,6 +197,15 @@ export const layout = () => {
// wait for flex grid styles to be applied to all windows and trigger dom layout
windowGridInfo.forEach(({ gridId }) => windows.get(gridId)!.refreshLayout())
refreshWebGLGrid()
+
+ // cursorline width does not always get resized correctly after window
+ // layout changes, so we will force an update of the cursor to make sure
+ // it is correct. test case: two vert splits, move to left and :bo
+ state.activeGrid &&
+ requestAnimationFrame(() => {
+ if (!windows.has(state.activeGrid)) return
+ moveCursor(cursor.row, cursor.col)
+ })
}
const updateWindowNameplates = () =>
From 4c9a33efd559a4d4190238d35b280b7560fe44f8 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Wed, 11 Nov 2020 12:53:49 -0600
Subject: [PATCH 18/26] Questionable code to make the cursor not appear in
inactive windows
---
src/core/cursor.ts | 3 +++
src/render/webgl.ts | 18 ++++++++++++++++--
src/windows/window-manager.ts | 5 ++++-
src/windows/window.ts | 5 ++++-
4 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index ad8e8f18..9d2e4d07 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -8,6 +8,7 @@ export enum CursorShape {
}
export const cursor = {
+ visible: false,
row: 0,
col: 0,
color: [0, 0, 0],
@@ -44,6 +45,7 @@ export const hideCursor = () => {
cursorRequestedToBeHidden = true
windows.webgl.showCursor(false)
+ Object.assign(cursor, { visible: false })
}
export const showCursor = () => {
@@ -51,6 +53,7 @@ export const showCursor = () => {
cursorRequestedToBeHidden = false
windows.webgl.showCursor(true)
+ Object.assign(cursor, { visible: true })
}
// export const showCursorline = () => (cursorline.style.display = '')
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 8152ce14..6623e233 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -3,7 +3,8 @@ import CreateWebGL from '../render/webgl-utils'
import { cell } from '../core/workspace'
import TextFG from '../render/webgl-text-fg'
import TextBG from '../render/webgl-text-bg'
-import { CursorShape } from '../core/cursor'
+import { cursor as cursorState, CursorShape } from '../core/cursor'
+import { getActiveGridId } from '../windows/window-manager'
export interface WebGLView {
resize: (rows: number, cols: number) => void
@@ -18,6 +19,7 @@ export interface WebGLView {
getGridLine: (row: number) => Float32Array
getGridBuffer: () => Float32Array
getBuffer: () => Float32Array
+ updateGridId: (gridId: number) => void
}
const nutella = () => {
@@ -61,12 +63,15 @@ const nutella = () => {
textFGRenderer.clearAll()
}
- const createView = (): WebGLView => {
+ const createView = (initialGridId: number): WebGLView => {
+ let gridId = initialGridId
const viewport = { x: 0, y: 0, width: 0, height: 0 }
const gridSize = { rows: 0, cols: 0 }
const gridBuffer = CreateWebGLBuffer()
let dataBuffer = new Float32Array()
+ const updateGridId = (newGridId: number) => gridId = newGridId
+
const resize = (rows: number, cols: number) => {
const width = cols * cell.width
const height = rows * cell.height
@@ -96,15 +101,23 @@ const nutella = () => {
const render = (elements: number) => {
const buffer = dataBuffer.subarray(0, elements)
const { x, y, width, height } = viewport
+
+ const doHacks = gridId !== getActiveGridId() && cursorState.visible
+ if (doHacks) showCursor(false)
textBGRenderer.render(buffer, x, y, width, height)
textFGRenderer.render(buffer, x, y, width, height)
+ if (doHacks) showCursor(true)
}
const renderGridBuffer = () => {
const { x, y, width, height } = viewport
const buffer = gridBuffer.getBuffer()
+
+ const doHacks = gridId !== getActiveGridId() && cursorState.visible
+ if (doHacks) showCursor(false)
textBGRenderer.render(buffer, x, y, width, height)
textFGRenderer.render(buffer, x, y, width, height)
+ if (doHacks) showCursor(true)
}
const clear = () => {
@@ -140,6 +153,7 @@ const nutella = () => {
moveRegionDown,
clearGridBuffer,
renderGridBuffer,
+ updateGridId,
getGridCell: gridBuffer.getCell,
getGridLine: gridBuffer.getLine,
getGridBuffer: gridBuffer.getBuffer,
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index d6a25ed2..714c19f1 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -75,7 +75,9 @@ export const calculateGlobalOffset = (anchorWin: Window, float: Window) => {
}
}
-export const createWebGLView = () => webgl.createView()
+export const createWebGLView = (gridId: number) => webgl.createView(gridId)
+
+export const getActiveGridId = () => state.activeInstanceGrid
export const setActiveGrid = (id: number) =>
Object.assign(state, {
@@ -115,6 +117,7 @@ export const set = (
visible: true,
id: wid,
gridId: gid,
+ gridIdNumber: gridId,
})
if (!windows.has(gid)) windows.set(gid, win)
diff --git a/src/windows/window.ts b/src/windows/window.ts
index 0649a1d2..d738d70b 100644
--- a/src/windows/window.ts
+++ b/src/windows/window.ts
@@ -14,6 +14,7 @@ import { makel } from '../ui/vanilla'
export interface WindowInfo {
id: string
gridId: string
+ gridIdNumber: number
row: number
col: number
width: number
@@ -116,6 +117,7 @@ export default () => {
const wininfo: WindowInfo = {
id: '0',
gridId: '0',
+ gridIdNumber: 0,
row: 0,
col: 0,
width: 0,
@@ -125,7 +127,7 @@ export default () => {
anchor: '',
}
const layout = { x: 0, y: 0, width: 0, height: 0 }
- const webgl = createWebGLView()
+ const webgl = createWebGLView(0)
const container = makel({
flexFlow: 'column',
@@ -229,6 +231,7 @@ export default () => {
container.id = `${info.id}`
container.setAttribute('gridid', info.gridId)
+ webgl.updateGridId(info.gridIdNumber)
Object.assign(wininfo, info)
}
From 209ca5ce70d5a4955c4ad784c069734bb17010a0 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 12 Nov 2020 13:42:25 -0600
Subject: [PATCH 19/26] Show char under cursor (block), fix underlines
---
src/render/webgl-text-bg.ts | 87 ++++++++++++++++++++++---------------
src/render/webgl-text-fg.ts | 47 +++++++++++++++++++-
src/render/webgl.ts | 22 ++++++++--
3 files changed, 115 insertions(+), 41 deletions(-)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 704e52ef..4867696b 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -110,7 +110,7 @@ export default (webgl: WebGL) => {
colorAtlas.height
)
webgl.gl.uniform2f(program.vars.cursorPosition, 0, 0)
- webgl.gl.uniform4fv(program.vars.cursorColor, [0, 0, 0, 1])
+ webgl.gl.uniform4fv(program.vars.cursorColor, [1, 1, 1, 1])
// @ts-ignore
webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor)
@@ -186,43 +186,53 @@ export default (webgl: WebGL) => {
w6th,
0,
- // TODO(smolck): More compact way of doing this. Also, note that the 1's
+ // TODO(smolck): Better way of doing this? Also, note that the 1's
// specify which triangles of the above to color in for the cursor, and the zeroes
// which triangles not to color in, *if* the cursor is a line shape. If
// it isn't a line shape (atm a block shape), these are ignored.
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ ...Array(6).fill(1),
+ ...Array(6).fill(0),
]),
+ // TODO(smolck): Don't draw double the tris for underliens too, maybe use
+ // a separate buffer for quadVertex somehow or something?
lines: new Float32Array([
+ /* Previous values (for future ref):
+ * 0, cell.height - 1,
+ * cell.width, cell.height,
+ * 0, cell.height,
+ *
+ * cell.width, cell.height - 1,
+ * cell.width, cell.height,
+ * 0, cell.height - 1, */
0,
- cell.height - 1,
- cell.width,
- cell.height,
- 0,
- cell.height,
- cell.width,
- cell.height - 1,
- cell.width,
- cell.height,
+ h - 1,
+ w6th,
+ h,
0,
- cell.height - 1,
+ h,
+ w6th,
+ h - 1,
+ w6th,
+ h,
0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ h - 1,
+
+ w6th,
+ h - 1,
+ w,
+ h,
+ w6th,
+ h,
+
+ w,
+ h - 1,
+ w,
+ h,
+ w6th,
+ h - 1,
+
+ ...Array(12).fill(0),
]),
}
@@ -281,19 +291,24 @@ export default (webgl: WebGL) => {
// underlines
quadBuffer.setData(quads.lines)
- // @ts-ignore TODO(smolck): HACKS
- if (shouldShowCursor) webgl.gl.uniform1i(program.vars.shouldShowCursor, false)
-
+ // @ts-ignore <- for using a boolean with `uniform1i`
+ // Just want to ignore the cursor logic in the vertex shader for underlines,
+ // so set shouldShowCursor to false, then back to it's previous value after
+ // the draw call.
+ if (shouldShowCursor)
+ // @ts-ignore
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, false)
webgl.gl.uniform1f(program.vars.hlidType, 2)
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
-
- // @ts-ignore TODO(smolck): HACKS
+ // @ts-ignore
webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor)
}
- const showCursor = (enable: boolean) =>
+ const showCursor = (enable: boolean) => (
+ (shouldShowCursor = enable),
// @ts-ignore
- (shouldShowCursor = enable, webgl.gl.uniform1i(program.vars.shouldShowCursor, enable))
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, enable)
+ )
const updateCursorColor = (color: [number, number, number]) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
diff --git a/src/render/webgl-text-fg.ts b/src/render/webgl-text-fg.ts
index fe79b017..643c4f9b 100644
--- a/src/render/webgl-text-fg.ts
+++ b/src/render/webgl-text-fg.ts
@@ -2,6 +2,7 @@ import { getColorAtlas } from '../render/highlight-attributes'
import generateFontAtlas from '../render/font-texture-atlas'
import { WebGL, VarKind } from '../render/webgl-utils'
import { cell } from '../core/workspace'
+import { CursorShape } from '../core/cursor'
export default (webgl: WebGL) => {
const viewport = { x: 0, y: 0, width: 0, height: 0 }
@@ -18,6 +19,11 @@ export default (webgl: WebGL) => {
colorAtlasTextureId: VarKind.Uniform,
cellSize: VarKind.Uniform,
cellPadding: VarKind.Uniform,
+
+ shouldShowCursor: VarKind.Uniform,
+ cursorPosition: VarKind.Uniform,
+ cursorShape: VarKind.Uniform,
+ cursorColor: VarKind.Uniform,
})
program.setVertexShader(
@@ -33,10 +39,17 @@ export default (webgl: WebGL) => {
uniform vec2 ${v.cellPadding};
uniform sampler2D ${v.colorAtlasTextureId};
+ uniform vec4 ${v.cursorColor};
+ uniform vec2 ${v.cursorPosition};
+ uniform bool ${v.shouldShowCursor};
+ uniform int ${v.cursorShape};
+
out vec2 o_glyphPosition;
out vec4 o_color;
void main() {
+ bool isCursorCell = ${v.cursorPosition} == ${v.cellPosition} && ${v.shouldShowCursor};
+
vec2 absolutePixelPosition = ${v.cellPosition} * ${v.cellSize};
vec2 vertexPosition = absolutePixelPosition + ${v.quadVertex} + ${v.cellPadding};
vec2 posFloat = vertexPosition / ${v.canvasResolution};
@@ -53,7 +66,13 @@ export default (webgl: WebGL) => {
float color_y = 1.0 * texelSize + 1.0;
vec2 colorPosition = vec2(color_x, color_y) / ${v.colorAtlasResolution};
- o_color = texture(${v.colorAtlasTextureId}, colorPosition);
+ vec4 textureColor = texture(${v.colorAtlasTextureId}, colorPosition);
+
+ if (isCursorCell && cursorShape == 0) {
+ o_color = ${v.cursorColor};
+ } else {
+ o_color = textureColor;
+ }
}
`
)
@@ -104,6 +123,12 @@ export default (webgl: WebGL) => {
colorAtlas.height
)
+ webgl.gl.uniform4fv(program.vars.cursorColor, [0, 0, 0, 1])
+ webgl.gl.uniform2f(program.vars.cursorPosition, 0, 0)
+ webgl.gl.uniform1i(program.vars.cursorShape, 0) // CursorShape.block = 0
+ // @ts-ignore
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, true)
+
// total size of all pointers. chunk size that goes to shader
const wrenderStride = 4 * Float32Array.BYTES_PER_ELEMENT
@@ -231,6 +256,22 @@ export default (webgl: WebGL) => {
webgl.gl.uniform2f(program.vars.cellPadding, 0, cell.padding)
}
+ const showCursor = (enable: boolean) =>
+ // @ts-ignore
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, enable)
+
+ const updateCursorColor = (color: [number, number, number]) => {
+ webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
+ }
+
+ const updateCursorShape = (shape: CursorShape) => {
+ webgl.gl.uniform1i(program.vars.cursorShape, shape)
+ }
+
+ const updateCursorPosition = (row: number, col: number) => {
+ webgl.gl.uniform2f(program.vars.cursorPosition, col, row)
+ }
+
const updateColorAtlas = (colorAtlas: HTMLCanvasElement) => {
webgl.loadCanvasTexture(colorAtlas, webgl.gl.TEXTURE1)
webgl.gl.uniform2f(
@@ -263,5 +304,9 @@ export default (webgl: WebGL) => {
updateFontAtlas,
updateColorAtlas,
updateCellSize,
+ updateCursorPosition,
+ updateCursorShape,
+ updateCursorColor,
+ showCursor,
}
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 6623e233..c4273887 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -34,15 +34,28 @@ const nutella = () => {
textFGRenderer.resize(width, height)
}
- const showCursor = (enable: boolean) => textBGRenderer.showCursor(enable)
+ const showCursor = (enable: boolean) => {
+ textBGRenderer.showCursor(enable)
+ textFGRenderer.showCursor(enable)
+ }
+
+ const updateCursorShape = (shape: CursorShape) => {
+ textBGRenderer.updateCursorShape(shape)
+ textFGRenderer.updateCursorShape(shape)
+ }
- const updateCursorShape = (shape: CursorShape) => textBGRenderer.updateCursorShape(shape)
+ // const updateCharUnderCursorColor = (r: number, g: number, b: number) =>
+ // textFGRenderer.updateCursorColor([r, g, b])
- const updateCursorColor = (r: number, g: number, b: number) =>
+ const updateCursorColor = (r: number, g: number, b: number) => {
textBGRenderer.updateCursorColor([r, g, b])
+ textFGRenderer.updateCursorColor([1.0 - r, 1.0 - g, 1.0 - b])
+ }
- const updateCursorPosition = (row: number, col: number) =>
+ const updateCursorPosition = (row: number, col: number) => {
textBGRenderer.updateCursorPosition(row, col)
+ textFGRenderer.updateCursorPosition(row, col)
+ }
const updateFontAtlas = (fontAtlas: HTMLCanvasElement) => {
textFGRenderer.updateFontAtlas(fontAtlas)
@@ -171,6 +184,7 @@ const nutella = () => {
updateCursorShape,
updateCursorPosition,
updateCursorColor,
+ // updateCharUnderCursorColor,
showCursor,
foregroundElement: foregroundGL.canvasElement,
backgroundElement: backgroundGL.canvasElement,
From ae933dd779a9ee7f2749ce03252950c1bca74267 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 12 Nov 2020 15:37:35 -0600
Subject: [PATCH 20/26] Obey size of cursor
---
src/core/cursor.ts | 1 +
src/render/webgl-text-bg.ts | 34 +++++++++++++++++++---------------
src/render/webgl.ts | 6 ++----
3 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index 9d2e4d07..19fd4353 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -24,6 +24,7 @@ let cursorRequestedToBeHidden = false
export const setCursorShape = (shape: CursorShape, size = 20) => {
cursor.shape = shape
cursor.size = size;
+
windows.webgl.updateCursorShape(shape)
}
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index 4867696b..a86451c3 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -2,11 +2,12 @@ import { getColorAtlas, colors } from '../render/highlight-attributes'
import { WebGL, VarKind } from '../render/webgl-utils'
import { cell } from '../core/workspace'
import { hexToRGB } from '../ui/css'
-import { CursorShape } from '../core/cursor'
+import { CursorShape, } from '../core/cursor'
export default (webgl: WebGL) => {
const viewport = { x: 0, y: 0, width: 0, height: 0 }
let shouldShowCursor = true
+ let cursorSize = 20
const program = webgl.setupProgram({
quadVertex: VarKind.Attribute,
@@ -151,39 +152,39 @@ export default (webgl: WebGL) => {
},
])
- const updateCellSize = (initial = false) => {
+ const updateCellSize = (initial = false, cursorSize = 20) => {
const w = cell.width
const h = cell.height
- const w6th = w / 6
+ const smallerW = w * (cursorSize / 100.0)
const next = {
boxes: new Float32Array([
0,
0,
- w6th,
+ smallerW,
h,
0,
h,
- w6th,
+ smallerW,
0,
- w6th,
+ smallerW,
h,
0,
0,
- w6th,
+ smallerW,
0,
w,
h,
- w6th,
+ smallerW,
h,
w,
0,
w,
h,
- w6th,
+ smallerW,
0,
// TODO(smolck): Better way of doing this? Also, note that the 1's
@@ -206,30 +207,30 @@ export default (webgl: WebGL) => {
* 0, cell.height - 1, */
0,
h - 1,
- w6th,
+ smallerW,
h,
0,
h,
- w6th,
+ smallerW,
h - 1,
- w6th,
+ smallerW,
h,
0,
h - 1,
- w6th,
+ smallerW,
h - 1,
w,
h,
- w6th,
+ smallerW,
h,
w,
h - 1,
w,
h,
- w6th,
+ smallerW,
h - 1,
...Array(12).fill(0),
@@ -314,6 +315,8 @@ export default (webgl: WebGL) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
}
+ const updateCursorSize = (size: number) => cursorSize = size
+
const updateCursorShape = (shape: CursorShape) => {
webgl.gl.uniform1i(program.vars.cursorShape, shape)
}
@@ -360,6 +363,7 @@ export default (webgl: WebGL) => {
showCursor,
updateCursorPosition,
updateCursorShape,
+ updateCursorSize,
updateCursorColor,
}
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index c4273887..2f7b42f1 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -41,12 +41,11 @@ const nutella = () => {
const updateCursorShape = (shape: CursorShape) => {
textBGRenderer.updateCursorShape(shape)
+ textBGRenderer.updateCellSize(false, cursorState.size)
+
textFGRenderer.updateCursorShape(shape)
}
- // const updateCharUnderCursorColor = (r: number, g: number, b: number) =>
- // textFGRenderer.updateCursorColor([r, g, b])
-
const updateCursorColor = (r: number, g: number, b: number) => {
textBGRenderer.updateCursorColor([r, g, b])
textFGRenderer.updateCursorColor([1.0 - r, 1.0 - g, 1.0 - b])
@@ -184,7 +183,6 @@ const nutella = () => {
updateCursorShape,
updateCursorPosition,
updateCursorColor,
- // updateCharUnderCursorColor,
showCursor,
foregroundElement: foregroundGL.canvasElement,
backgroundElement: backgroundGL.canvasElement,
From 951c6ec5c5d0e2759ef58b91905a7ad39af0e44b Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Thu, 12 Nov 2020 15:43:42 -0600
Subject: [PATCH 21/26] comment
---
src/render/webgl.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 2f7b42f1..064d5395 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -41,6 +41,7 @@ const nutella = () => {
const updateCursorShape = (shape: CursorShape) => {
textBGRenderer.updateCursorShape(shape)
+ // TODO(smolck): If cursor size changes need to update cells . . .
textBGRenderer.updateCellSize(false, cursorState.size)
textFGRenderer.updateCursorShape(shape)
From c4898b4c2e2dce3e1e291a76e21d9bc064b6e99a Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sat, 14 Nov 2020 19:50:26 -0600
Subject: [PATCH 22/26] Revert 2fabcbb
https://github.com/smolck/uivonim/commit/2fabcbb21037faeb9d4a73faddab3a49e15cdde0
caused issues with the cursor lagging, so revert it (for now?).
---
src/render/redraw.ts | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
diff --git a/src/render/redraw.ts b/src/render/redraw.ts
index ac2f4e0c..13dbbcf0 100644
--- a/src/render/redraw.ts
+++ b/src/render/redraw.ts
@@ -302,20 +302,6 @@ const win_float_pos = (e: any) => {
}
}
-let layoutTimeout: NodeJS.Timeout | undefined
-
-const refreshOrStartLayoutTimer = (winUpdates: boolean) => {
- layoutTimeout = setTimeout(() => {
- renderEvents.messageClearPromptsMaybeHack(state_cursorVisible)
- state_cursorVisible ? showCursor() : hideCursor()
- dispatch.pub('redraw')
- if (!winUpdates) return
-
- windows.disposeInvalidWindows()
- windows.layout()
- }, 10)
-}
-
onRedraw((redrawEvents) => {
// because of circular logic/infinite loop. cmdline_show updates UI, UI makes
// a change in the cmdline, nvim sends redraw again. we cut that stuff out
@@ -380,6 +366,11 @@ onRedraw((redrawEvents) => {
else if (e === 'msg_ruler') renderEvents.msg_ruler(ev)
}
- if (layoutTimeout) clearTimeout(layoutTimeout)
- refreshOrStartLayoutTimer(winUpdates)
+ renderEvents.messageClearPromptsMaybeHack(state_cursorVisible)
+ state_cursorVisible ? showCursor() : hideCursor()
+ dispatch.pub('redraw')
+ if (!winUpdates) return
+
+ windows.disposeInvalidWindows()
+ windows.layout()
})
From 8741acdca56d36d2f4158ba01a4195828556baf7 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sat, 14 Nov 2020 19:51:35 -0600
Subject: [PATCH 23/26] proper amount of vertices for underlines
---
src/render/webgl-text-bg.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index a86451c3..d826cb3a 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -300,7 +300,7 @@ export default (webgl: WebGL) => {
// @ts-ignore
webgl.gl.uniform1i(program.vars.shouldShowCursor, false)
webgl.gl.uniform1f(program.vars.hlidType, 2)
- webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 6, buffer.length / 4)
+ webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 12, buffer.length / 4)
// @ts-ignore
webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor)
}
From 22502744f1db7c2700b964b9a1282ab80356c5f4 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sat, 14 Nov 2020 20:06:59 -0600
Subject: [PATCH 24/26] Support horizontal guicursor and format
---
src/core/cursor.ts | 2 +-
src/render/webgl-text-bg.ts | 36 ++++++++++++++++++-----------------
src/render/webgl.ts | 2 +-
src/windows/window-manager.ts | 1 -
4 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index 19fd4353..baaa98da 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -23,7 +23,7 @@ let cursorRequestedToBeHidden = false
export const setCursorShape = (shape: CursorShape, size = 20) => {
cursor.shape = shape
- cursor.size = size;
+ cursor.size = size
windows.webgl.updateCursorShape(shape)
}
diff --git a/src/render/webgl-text-bg.ts b/src/render/webgl-text-bg.ts
index d826cb3a..693b4ed7 100644
--- a/src/render/webgl-text-bg.ts
+++ b/src/render/webgl-text-bg.ts
@@ -2,12 +2,12 @@ import { getColorAtlas, colors } from '../render/highlight-attributes'
import { WebGL, VarKind } from '../render/webgl-utils'
import { cell } from '../core/workspace'
import { hexToRGB } from '../ui/css'
-import { CursorShape, } from '../core/cursor'
+import { CursorShape } from '../core/cursor'
export default (webgl: WebGL) => {
const viewport = { x: 0, y: 0, width: 0, height: 0 }
let shouldShowCursor = true
- let cursorSize = 20
+ let cursorShape = 0 /* CursorShape.block */
const program = webgl.setupProgram({
quadVertex: VarKind.Attribute,
@@ -156,6 +156,7 @@ export default (webgl: WebGL) => {
const w = cell.width
const h = cell.height
const smallerW = w * (cursorSize / 100.0)
+ const percentH = h * (cursorSize / 100.0)
const next = {
boxes: new Float32Array([
@@ -208,28 +209,28 @@ export default (webgl: WebGL) => {
0,
h - 1,
smallerW,
- h,
+ percentH,
0,
- h,
+ percentH,
smallerW,
h - 1,
smallerW,
- h,
+ percentH,
0,
h - 1,
smallerW,
h - 1,
w,
- h,
+ percentH,
smallerW,
- h,
+ percentH,
w,
h - 1,
w,
- h,
+ percentH,
smallerW,
h - 1,
@@ -284,25 +285,28 @@ export default (webgl: WebGL) => {
readjustViewportMaybe(x, y, width, height)
wrenderBuffer.setData(buffer)
+ if (shouldShowCursor && cursorShape == 2)
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, 0 /* false */)
// background
quadBuffer.setData(quads.boxes)
webgl.gl.uniform1f(program.vars.hlidType, 0)
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 12, buffer.length / 4)
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor ? 1 : 0)
+
// underlines
quadBuffer.setData(quads.lines)
- // @ts-ignore <- for using a boolean with `uniform1i`
// Just want to ignore the cursor logic in the vertex shader for underlines,
// so set shouldShowCursor to false, then back to it's previous value after
// the draw call.
- if (shouldShowCursor)
- // @ts-ignore
- webgl.gl.uniform1i(program.vars.shouldShowCursor, false)
+ if (shouldShowCursor && cursorShape != 2 /* CursorShape.underline */)
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, 0 /* false */)
+
webgl.gl.uniform1f(program.vars.hlidType, 2)
webgl.gl.drawArraysInstanced(webgl.gl.TRIANGLES, 0, 12, buffer.length / 4)
- // @ts-ignore
- webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor)
+
+ webgl.gl.uniform1i(program.vars.shouldShowCursor, shouldShowCursor ? 1 : 0)
}
const showCursor = (enable: boolean) => (
@@ -315,9 +319,8 @@ export default (webgl: WebGL) => {
webgl.gl.uniform4fv(program.vars.cursorColor, [...color, 1])
}
- const updateCursorSize = (size: number) => cursorSize = size
-
const updateCursorShape = (shape: CursorShape) => {
+ cursorShape = shape
webgl.gl.uniform1i(program.vars.cursorShape, shape)
}
@@ -363,7 +366,6 @@ export default (webgl: WebGL) => {
showCursor,
updateCursorPosition,
updateCursorShape,
- updateCursorSize,
updateCursorColor,
}
}
diff --git a/src/render/webgl.ts b/src/render/webgl.ts
index 064d5395..d689c655 100644
--- a/src/render/webgl.ts
+++ b/src/render/webgl.ts
@@ -83,7 +83,7 @@ const nutella = () => {
const gridBuffer = CreateWebGLBuffer()
let dataBuffer = new Float32Array()
- const updateGridId = (newGridId: number) => gridId = newGridId
+ const updateGridId = (newGridId: number) => (gridId = newGridId)
const resize = (rows: number, cols: number) => {
const width = cols * cell.width
diff --git a/src/windows/window-manager.ts b/src/windows/window-manager.ts
index 714c19f1..036ff991 100644
--- a/src/windows/window-manager.ts
+++ b/src/windows/window-manager.ts
@@ -9,7 +9,6 @@ import { throttle } from '../support/utils'
import windowSizer from '../windows/sizer'
import api from '../core/instance-api'
-
export const size = { width: 0, height: 0 }
export const webgl = CreateWebGLRenderer()
const windows = new Map()
From 47729c9b6f8a329b39f225fe49d9d779eb57b0c7 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sat, 14 Nov 2020 20:09:05 -0600
Subject: [PATCH 25/26] "Fix" TS errors
---
src/components/extensions/grep.tsx | 4 ++--
src/components/extensions/lsp-references.tsx | 4 ++--
src/core/cursor.ts | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/components/extensions/grep.tsx b/src/components/extensions/grep.tsx
index 98cb546a..fcef0e57 100644
--- a/src/components/extensions/grep.tsx
+++ b/src/components/extensions/grep.tsx
@@ -1,7 +1,7 @@
import { RowNormal, RowHeader } from '../row-container'
import { PluginRight } from '../plugin-container'
import { vimBlur, vimFocus } from '../../ui/uikit'
-import { showCursorline } from '../../core/cursor'
+// TODO(smolck): import { showCursorline } from '../../core/cursor'
import Input from '../text-input'
import { badgeStyle } from '../../ui/styles'
import { render } from 'inferno'
@@ -67,7 +67,7 @@ const selectResult = (results: Result[], ix: number, subix: number) => {
const [path, items] = results[ix]
const { line, column } = items[subix]
api.nvim.jumpTo({ path, line, column })
- showCursorline()
+ // TODO(smolck): showCursorline()
}
const highlightPattern = (
diff --git a/src/components/extensions/lsp-references.tsx b/src/components/extensions/lsp-references.tsx
index 20f75c17..1f557f9c 100644
--- a/src/components/extensions/lsp-references.tsx
+++ b/src/components/extensions/lsp-references.tsx
@@ -2,7 +2,7 @@ import { RowNormal, RowHeader } from '../row-container'
import { PluginRight } from '../plugin-container'
import { vimBlur, vimFocus } from '../../ui/uikit'
import { simplifyPath } from '../../support/utils'
-import { showCursorline } from '../../core/cursor'
+// TODO(smolck): import { showCursorline } from '../../core/cursor'
import { badgeStyle } from '../../ui/styles'
import { render } from 'inferno'
import Input from '../text-input'
@@ -82,7 +82,7 @@ const selectResult = (references: Refs[], ix: number, subix: number) => {
line: lineNum - 1,
column: column - 1,
})
- showCursorline()
+ // TODO(smolck): showCursorline()
}
const highlightPattern = (
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index baaa98da..ed7d7fe3 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -57,7 +57,7 @@ export const showCursor = () => {
Object.assign(cursor, { visible: true })
}
-// export const showCursorline = () => (cursorline.style.display = '')
+// TODO(smolck): export const showCursorline = () => (cursorline.style.display = '')
export const moveCursor = (row: number, col: number) => {
Object.assign(cursor, { row, col })
From 596675f3c2a047a797624dcb264085932ab787f2 Mon Sep 17 00:00:00 2001
From: smolck <46855713+smolck@users.noreply.github.com>
Date: Sat, 14 Nov 2020 20:10:37 -0600
Subject: [PATCH 26/26] cleanup
---
src/bootstrap/index.html | 2 --
src/core/cursor.ts | 2 --
2 files changed, 4 deletions(-)
diff --git a/src/bootstrap/index.html b/src/bootstrap/index.html
index f07f6a57..6f3e8c43 100644
--- a/src/bootstrap/index.html
+++ b/src/bootstrap/index.html
@@ -166,8 +166,6 @@
diff --git a/src/core/cursor.ts b/src/core/cursor.ts
index ed7d7fe3..2660825a 100644
--- a/src/core/cursor.ts
+++ b/src/core/cursor.ts
@@ -18,8 +18,6 @@ export const cursor = {
let cursorEnabled = false
let cursorRequestedToBeHidden = false
-// export const getCursorBoundingClientRect = () =>
-// cursorline.getBoundingClientRect()
export const setCursorShape = (shape: CursorShape, size = 20) => {
cursor.shape = shape