Skip to content

Commit

Permalink
multigrid: prevent floating window stealing focus
Browse files Browse the repository at this point in the history
  • Loading branch information
Yatao Li committed Nov 2, 2020
1 parent 4d1717a commit 97881d3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
27 changes: 23 additions & 4 deletions ViewModels/EditorViewModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
let mutable m_griddirty = false // if true, the whole grid needs to be redrawn.
let mutable m_fontsize = theme.fontsize
let mutable m_glyphsize = Size(10.0, 10.0)
let mutable m_gridfocused = false
let mutable m_gridfocusable = true

let mutable m_fb_h = 10.0
let mutable m_fb_w = 10.0
Expand Down Expand Up @@ -265,7 +267,17 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
let setMouse (en:bool) =
m_mouse_en <- en

let setWinPos startrow startcol r c =
let closeGrid() =
trace _gridid "%s" "closeGrid"
if this.IsFocused then
this.IsFocused <- false
match parent with
| Some p ->
trace _gridid "try focus parent, id = %d" p.GridId
if p.Focusable then p.IsFocused <- true
| _ -> ()

let setWinPos startrow startcol r c f =
let parent =
match parent with
| Some p -> p
Expand All @@ -278,6 +290,7 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
initBuffer r c true
this.X <- origin.X
this.Y <- origin.Y
this.Focusable <- f

let hidePopupMenu() =
m_popupmenu_vm.Show <- false
Expand Down Expand Up @@ -331,9 +344,10 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
| ModeChange(name, index) -> changeMode name index
| Busy is_busy -> setBusy is_busy
| Mouse en -> setMouse en
| WinPos(_, _, startrow, startcol, c, r) -> setWinPos startrow startcol r c
| MsgSetPos(_, row, scrolled, sep_char) -> setWinPos row 0 1 m_gridsize.cols
| WinFloatPos (_, _, anchor, anchor_grid, r, c, f) -> setWinPos (int r + 1) (int c) m_gridsize.rows m_gridsize.cols // XXX assume attaching to grid #1, assume NW
| WinClose(_) -> closeGrid()
| WinPos(_, _, startrow, startcol, c, r) -> setWinPos startrow startcol r c true
| MsgSetPos(_, row, scrolled, sep_char) -> setWinPos row 0 1 m_gridsize.cols true
| WinFloatPos (_, _, anchor, anchor_grid, r, c, f) -> setWinPos (int r + 1) (int c) m_gridsize.rows m_gridsize.cols f // XXX assume attaching to grid #1, assume NW
| PopupMenuShow(items, selected, row, col, grid) -> showPopupMenu grid items selected row col
| PopupMenuSelect(selected) -> selectPopupMenuPassive selected
| PopupMenuHide -> hidePopupMenu ()
Expand Down Expand Up @@ -411,6 +425,9 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz

States.Register.Watch "font" fontConfig

this.ObservableForProperty(fun x -> x.IsFocused)
|> Observable.subscribe (fun x ->
trace _gridid "focus state changed: %A" x.Value)
]

interface IGridUI with
Expand Down Expand Up @@ -476,6 +493,8 @@ type EditorViewModel(_gridid: int, ?parent: EditorViewModel, ?_gridsize: GridSiz
member __.IsTopLevel with get(): bool = parent.IsNone
member __.GridId with get() = _gridid
member __.ChildGrids = m_child_grids
member __.IsFocused with get() = m_gridfocused and set(v) = ignore <| this.RaiseAndSetIfChanged(&m_gridfocused, v)
member __.Focusable with get() = m_gridfocusable and set(v) = ignore <| this.RaiseAndSetIfChanged(&m_gridfocusable, v)

(******************* Events ***********************)

Expand Down
2 changes: 1 addition & 1 deletion Views/Editor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:fvim = "clr-namespace:FVim;assembly=FVim"
Focusable = "True"
Focusable = "{Binding Focusable}"
x:Class = "FVim.Editor"
Background = "Transparent"
Design.Height="300"
Expand Down
14 changes: 12 additions & 2 deletions Views/Editor.xaml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,22 @@ type Editor() as this =
|> Observable.firstIf(fun _ -> this.IsInitialized && vm.Height > 0.0 && vm.Width > 0.0)
|> Observable.subscribe(fun _ ->
Model.OnGridReady(vm :> IGridUI)
ignore <| Dispatcher.UIThread.InvokeAsync(this.Focus))
if vm.Focusable then
ignore <| Dispatcher.UIThread.InvokeAsync(this.Focus))

this.GetObservable(RenderTickProperty).Subscribe(fun id ->
trace grid_vm "render tick %d" id
this.InvalidateVisual())

vm.ObservableForProperty(fun x -> x.IsFocused)
|> Observable.subscribe(fun focused ->
if focused.Value && not this.IsFocused then
trace grid_vm "%s" "viewmodel ask to focus"
this.Focus())

this.GotFocus.Subscribe(fun _ -> vm.IsFocused <- true)
this.LostFocus.Subscribe(fun _ -> vm.IsFocused <- false)

vm.ChildGrids.CollectionChanged.Subscribe(fun changes ->
match changes.Action with
| NotifyCollectionChangedAction.Add ->
Expand Down Expand Up @@ -354,7 +364,7 @@ type Editor() as this =
(*if m_debug then drawDebug grid_dc*)
grid_dc.PopClip()

grid_vm.markClean()
grid_vm.MarkClean()

let src_rect = Rect(0.0, 0.0, float grid_fb.PixelSize.Width, float grid_fb.PixelSize.Height)
let tgt_rect = Rect(0.0, 0.0, grid_fb.Size.Width, grid_fb.Size.Height)
Expand Down
2 changes: 1 addition & 1 deletion model.fs
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ let OnFocusGained() =
in ()
} |> run

let OnTerminated (args) =
let OnTerminated () =
trace "%s" "terminating nvim..."
nvim.stop 1

Expand Down

0 comments on commit 97881d3

Please sign in to comment.