Skip to content

Commit

Permalink
properly handle input events. add some comments wrt. keyboard layout.
Browse files Browse the repository at this point in the history
  • Loading branch information
yatli committed Mar 11, 2022
1 parent 04d0d60 commit 9f975b6
Show file tree
Hide file tree
Showing 16 changed files with 43 additions and 18 deletions.
17 changes: 9 additions & 8 deletions ViewModels/GridViewModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ open System
open model
open widgets
open System.Collections.Generic
open Avalonia.Interactivity

#nowarn "0025"

Expand Down Expand Up @@ -46,7 +47,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
let m_popupmenu_vm = new PopupMenuViewModel()
let m_child_grids = ResizeArray<GridViewModel>()
let m_resize_ev = Event<IGridUI>()
let m_input_ev = Event<int * InputEvent>()
let m_input_ev = Event<int * InputEvent * RoutedEventArgs>()
let m_ext_winclose_ev = Event<unit>()
let m_drawops = ResizeArray() // keeps the scroll and putBuffer operations

Expand Down Expand Up @@ -93,7 +94,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
static let mutable g_create_seq = 0
let m_create_seq = g_create_seq

let raiseInputEvent id e = m_input_ev.Trigger(id, e)
let raiseInputEvent id e ev = m_input_ev.Trigger(id, e, ev)

let getPos (p: Point) =
int(p.X / m_glyphsize.Width), int(p.Y / m_glyphsize.Height)
Expand Down Expand Up @@ -842,7 +843,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
(******************* Events ***********************)

member __.OnKey (e: KeyEventArgs) =
raiseInputEvent _gridid <| InputEvent.Key(e.KeyModifiers, e.Key)
raiseInputEvent _gridid (InputEvent.Key(e.KeyModifiers, e.Key)) e

member __.OnMouseDown (e: PointerPressedEventArgs) (root: Avalonia.VisualTree.IVisual) =
if m_mouse_en then
Expand All @@ -856,7 +857,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
m_mouse_pressed_widget <- wid
model.GuiWidgetMouseDown vm.BufNr wid
else
raiseInputEvent vm.GridId <| InputEvent.MousePress(e.KeyModifiers, r, c, button)
raiseInputEvent vm.GridId (InputEvent.MousePress(e.KeyModifiers, r, c, button)) e

member __.OnMouseUp (e: PointerReleasedEventArgs) (root: Avalonia.VisualTree.IVisual) =
if m_mouse_en then
Expand All @@ -869,7 +870,7 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
model.GuiWidgetMouseUp m_mouse_pressed_vm.BufNr m_mouse_pressed_widget
m_mouse_pressed_widget <- -1
else
raiseInputEvent m_mouse_pressed_vm.GridId <| InputEvent.MouseRelease(e.KeyModifiers, r, c, button)
raiseInputEvent m_mouse_pressed_vm.GridId (InputEvent.MouseRelease(e.KeyModifiers, r, c, button)) e

member __.OnMouseMove (e: PointerEventArgs) (root: Avalonia.VisualTree.IVisual) =
if m_mouse_en && m_mouse_pressed <> MouseButton.None then
Expand All @@ -884,14 +885,14 @@ and GridViewModel(_gridid: int, ?_parent: GridViewModel, ?_gridsize: GridSize) a
#if DEBUG
trace m_mouse_pressed_vm.GridId "mousemove: %d %d" r c
#endif
raiseInputEvent m_mouse_pressed_vm.GridId <| InputEvent.MouseDrag(e.KeyModifiers, r, c, m_mouse_pressed)
raiseInputEvent m_mouse_pressed_vm.GridId (InputEvent.MouseDrag(e.KeyModifiers, r, c, m_mouse_pressed)) e

member __.OnMouseWheel (e: PointerWheelEventArgs) (root: Avalonia.VisualTree.IVisual) =
if m_mouse_en then
let x, y = e.GetPosition root |> getPos
let _, _, vm, r, c, _ = this.FindTargetVm y x
let dx, dy = e.Delta.X, e.Delta.Y
raiseInputEvent vm.GridId <| InputEvent.MouseWheel(e.KeyModifiers, r, c, dx, dy)
raiseInputEvent vm.GridId (InputEvent.MouseWheel(e.KeyModifiers, r, c, dx, dy)) e

member __.OnTextInput (e: TextInputEventArgs) =
raiseInputEvent _gridid <| InputEvent.TextInput(e.Text)
raiseInputEvent _gridid (InputEvent.TextInput(e.Text)) e
1 change: 0 additions & 1 deletion Views/Grid.xaml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ type Grid() as this =
let subscribeAndHandleInput fn (ob: IObservable<#Avalonia.Interactivity.RoutedEventArgs>) =
ob.Subscribe(fun e ->
if not e.Handled then
//e.Handled <- true
doWithDataContext(fn e))

let drawDebug(dc: IDrawingContextImpl) =
Expand Down
34 changes: 26 additions & 8 deletions input.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ open neovim
open Avalonia.Input
open System
open FSharp.Control.Reactive
open Avalonia.Interactivity

let inline trace fmt = trace "input" fmt

Expand Down Expand Up @@ -270,6 +271,19 @@ let (|Special|Normal|Rejected|) (x: InputEvent) =
match x with
| Key(_, k) when RejectKeys.Contains k -> Rejected
| Key(DoesntBlockTextInput, k) when TextInputKeys.Contains k -> Rejected
// !!Note from here on, all TextInput-triggering keys should have been filtered.
// All that survived the purge are either non-textinput-triggering keys, or
// textinput-triggering keys with non-shift modifier active.
// The (possibly unwanted) side effect of this approach is the inconsistency
// between TextInput and modifier-active Key:
//
// | en-US kbd sequence | en result (sent to nvim) | de result (sent to nvim) |
// | ------------------ | ------------------------ | ------------------------ |
// | z | z | y |
// | Ctrl-z | <C-z> | <C-z> |
// | ' | ' | ä |
// | Ctrl-' | <C-'> | <C-'> |
//
| Key(m, Key.Back) ->
if m = KeyModifiers.Control then
blockNextTextInput <- true
Expand Down Expand Up @@ -379,21 +393,23 @@ let rec ModifiersPrefix (x: InputEvent) =
| TextInput _ -> ""
| _ -> ""

let onInput (nvim: Nvim) (input: IObservable<int*InputEvent>) =
let key,mouse = input |> Observable.partition(function | _, InputEvent.Key _ | _, InputEvent.TextInput _ -> true | _ -> false)
let onInput (nvim: Nvim) (input: IObservable<int*InputEvent*RoutedEventArgs>) =
let key,mouse = input |> Observable.partition(function | _, InputEvent.Key _, _ | _, InputEvent.TextInput _, _ -> true | _ -> false)
// translate to nvim input sequence
let key =
key
|> Observable.choose(fun (_, x) ->
|> Observable.choose(fun (_, x, ev) ->
match x with
| TextInput "<" -> Some "<LT>"
| TextInput txt ->
if blockNextTextInput then
| TextInput txt ->
ev.Handled <- true
if txt = "<" then Some "<LT>"
else if blockNextTextInput then
blockNextTextInput <- false
None
else
else
Some txt
| InputEvent.Key _ ->
ev.Handled <- true
let pref = ModifiersPrefix x
match x,pref with
| (Special sp), "" -> Some(sprintf "<%s>" sp)
Expand All @@ -404,13 +420,15 @@ let onInput (nvim: Nvim) (input: IObservable<int*InputEvent>) =
#if DEBUG
trace "rejected: %A" x
#endif
ev.Handled <- false
None
| _ -> None
)

let mouse =
mouse
|> Observable.choose(fun (gridid, x) ->
|> Observable.choose(fun (gridid, x, ev) ->
ev.Handled <- true
let pref = ModifiersPrefix x
match x with
| MousePress(_, r, c, NvimSupportedMouseButton but) -> Some(gridid, MB but, "press", r, c, 1, pref)
Expand Down
Binary file added profiling/FVim.exe_20210924_175836.nettrace
Binary file not shown.
1 change: 1 addition & 0 deletions profiling/FVim.exe_20210924_175836.speedscope.json

Large diffs are not rendered by default.

Binary file added profiling/FVim.exe_20210924_180242.nettrace
Binary file not shown.
1 change: 1 addition & 0 deletions profiling/FVim.exe_20210924_180242.speedscope.json

Large diffs are not rendered by default.

Binary file added profiling/FVim.exe_20210924_192551.nettrace
Binary file not shown.
1 change: 1 addition & 0 deletions profiling/FVim.exe_20210924_192551.speedscope.json

Large diffs are not rendered by default.

Binary file added profiling/FVim.exe_20210924_193534.nettrace
Binary file not shown.
1 change: 1 addition & 0 deletions profiling/FVim.exe_20210924_193534.speedscope.json

Large diffs are not rendered by default.

Binary file added profiling/FVim.exe_20210924_220949.nettrace
Binary file not shown.
1 change: 1 addition & 0 deletions profiling/FVim.exe_20210924_220949.speedscope.json

Large diffs are not rendered by default.

Binary file added profiling/FVim.exe_20210924_222802.nettrace
Binary file not shown.
1 change: 1 addition & 0 deletions profiling/FVim.exe_20210924_222802.speedscope.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion ui.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ open System
open Avalonia.Media.TextFormatting
open System.Globalization
open SkiaSharp
open Avalonia.Interactivity

#nowarn "0009"

Expand Down Expand Up @@ -100,7 +101,7 @@ type IGridUI =
/// Number of columns
abstract GridWidth: int
abstract Resized: IEvent<IGridUI>
abstract Input: IEvent<int*InputEvent>
abstract Input: IEvent<int*InputEvent*RoutedEventArgs>
abstract BackgroundColor: Color
abstract HasChildren: bool
abstract RenderScale: float
Expand Down

0 comments on commit 9f975b6

Please sign in to comment.