Eto WebView inactive keyboard

Hello !

I have a Eto WebView in a Rhino panel but inside the web page the keyboard : ctrl-c, ctrl-v, tab or directional are not capture. (this page works outside Rhino/Eto)

Do you have an idea?

Thanks!

@curtisw maybe you can help me!

I have make some test and with winforms or wpf I have the same problem
I made a simple Eto application independent of Rhino and I have everything except the directional keyboard

jmv

I know more,

I think the problem does not come from Eto

I have make a simple application Windows Forms (independent of Rhino) and a second Rhino with the same Control. And i have past multiple events handler for catch the keys

In a first program, all is ok. In second i not catch the navigation keys (left, right, tab) and spécial keys (ctrl, maj)…
Maybe an Rhino event listener that stops the progress.

I can not anymore. I’ll see how Speckle does.

It’s possible to have a functional Eto.Forms.WebView ???

What is worth doing. It’s worth doing well.

please test:

JavaScript inside the page does not receive directional events …

Or tell me how to trigger an event on an Eto control? (because Rhino App listens to events instead of Webview. Maybe i can redirect it ?)

I do think that Rhino captures many events. I wouldn’t be surprised if these didn’t work well.

Maybe @dale, @stevebaer or @JohnM can give more details.

Hello

it’s a shame and you recommend to use Eto.

I can now redirecting the event to the web page inside Eto WebView with

WebView.ExecuteScript ("document.dispatchEvent (...)");

That’s work well but the control loose immediately the focus in favour of the Rhino

How can I temporarily disable event listeners on RhinoApp ? Or stop the propagation ?

Thank you.

Hi @kitjmv,

I believe this is a fairly infamous problem.

Enter, ESC, Tab, etc., do not work in modeless dialog is as designed, since your dialog is child of Rhino’s main window. The message pump in this case is owned by Rhino. Therefore, all the keystroke messages are taken by the Rhino application and not dispatched to the modeless dialog box.

Inn the past, the workaround was to implement a WH_GETMESSAGE Windows hook. There is a sample of this using WinForms here in our GitHub repo:

https://github.com/mcneel/rhino-developer-samples/blob/6/rhinocommon/cs/SampleCsWinForms/Forms/SampleCsModelessTabFix.cs

However, I though we added a provision for this for WPF in Rhino 6.

Can you post the code to a sample project that isn’t working for you?

– Dale

Hello @dale !

Yes, I have a simple startup template in vs2017 without command (just the plugin file)

using System;
using System.IO;
using System.Reflection;
using Rhino.PlugIns;

namespace RhWebView
{
    public class RhWebViewPlugIn : Rhino.PlugIns.PlugIn
    {
        public static RhWebViewPlugIn Instance { get; private set; }

        public RhWebViewPlugIn()
        {
            Instance = this;
        }

        protected override LoadReturnCode OnLoad(ref string errorMessage)
        {
            Rhino.UI.Panels.RegisterPanel(this, typeof(Panel), "RhWebView", null);
            return base.OnLoad(ref errorMessage);
        }
    }
    
    [System.Runtime.InteropServices.Guid("244B0C87-BD56-4DB7-AB2C-F7CC170775B1")]
    public class Panel : Eto.Forms.Panel
    {
        public MyWebView browser;
        
        private bool isInEvent = false;

        public Panel()
        {
            browser = new MyWebView ();

            Content = new Eto.Forms.DynamicLayout
            {
                Rows = { new Eto.Forms.DynamicRow(browser) }
            };
        }
        
        protected override void OnLoadComplete(EventArgs e)
        {
            var fpath = (Directory.GetParent(Assembly.GetExecutingAssembly().Location) + "/app/index.html").Replace("\\", "/");
            browser.Url = new System.Uri(fpath);
            base.OnLoadComplete(e);
        }

        protected override void OnGotFocus(EventArgs e) // just shoot the first time, immediately followed by OnLostFocus
        {
            //isInEvent = true;
            Rhino.RhinoApp.WriteLine("+ WarpKeyboardEvent");
            Rhino.RhinoApp.KeyboardEvent += WarpKeyboardEvent;
        }

        protected override void OnLostFocus(EventArgs e) // so OnGotFocus & OnLostFocus is not useful here
        {
            //if ( isInEvent ) { isInEvent = false; return; }
            Rhino.RhinoApp.WriteLine("- WarpKeyboardEvent");
            //Rhino.RhinoApp.KeyboardEvent -= WarpKeyboardEvent;
        }

        protected void WarpKeyboardEvent(int key)
        {
            Rhino.RhinoApp.WriteLine("WarpKeyboardEvent");
            if (isInEvent) { isInEvent = false; return; } // the event is repeated several times, so multiple events can pass
            isInEvent = true;                             // these lines do not solve it
            var loffset = "";                             // (I guess this event is triggered every time like RhinoApp.Idle)
            var coffset = "";
            switch (key)
            {
                case 37: coffset = "- 1"; break;
                case 38: loffset = "- 1"; break;
                case 39: coffset = "+ 1"; break;
                case 40: loffset = "+ 1"; break;
            }
            browser.ExecuteScript(
                $"var pos = editor.getPosition(); editor.setPosition(new monaco.Position (pos.lineNumber {loffset}, pos.column {coffset}))"
            );
        }

        //protected override void OnMouseLeave(MouseEventArgs e) // no effect
        //protected override void OnMouseEnter(MouseEventArgs e) // no effect
        //protected override void OnTextInput(TextInputEventArgs e) // no effect
        //protected override void OnKeyDown(KeyEventArgs e) // no effect
        //protected override void OnKeyUp(KeyEventArgs e) // no effect
    }

    public class MyWebView : Eto.Forms.WebView
    {
        //protected override void OnKeyDown(KeyEventArgs e) // no effect
        //protected override void OnKeyUp(KeyEventArgs e) // no effect
        //protected override void OnMouseEnter(MouseEventArgs e) // no effect
        //protected override void OnMouseLeave(MouseEventArgs e) // no effect

        protected override void OnGotFocus(EventArgs e) // just shoot the first time, immediately followed by OnLostFocus
        { Rhino.RhinoApp.WriteLine("OnGotFocus"); }

        protected override void OnLostFocus(EventArgs e) // just the first time then nothing
        { Rhino.RhinoApp.WriteLine("OnLostFocus"); }

    }
}

and the content of the app/ directory

app.zip (530.1 KB)

And i have change: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION\rhino_fr-fr_6.7.18183.14071.exe to 11000

note for WarpKeyboardEvent listener that work with up, down, left, right key. But I think it’s not the right method because I do not know how to replace Ctl+C Ctrl+V Ctrl+X


My goal is to have a custom multilingual editor to attach scripts to objects or the document.
it could be:

  • A C# script to run directly in Rhino
  • A Markdown file to document part of 3D
  • A special js/glsl for writing in the webgl export

So I chose monaco editor (the editor of Visual Code) and the content of the editor must listen to the current selection. If the control is in a Modal dialog this project loses all its simplicity.

I tested several approaches:

  • With CefSharp, the editor is fully functional but I have an incompatibility with another library.
    For example: with the C# code i don’t use the same way of your Rhino Inside (because there is too much call between Rhino and the script), i use the Roslyn Script but Roslyn Script needs net46 and CefSharp has no target for this version.
    And CefSharp is very complex to just have a WebView control and to have a control for multi platforms.

  • I tested the editor in a non-modal external window (Electron) and simulate a dockable panel by positioning this window over Rhino.
    But here too I have a problems with Rhino listeners: RhinoEtoApp.MainWindow.SizeChanged has no effect!
    And here too it’s very complex for just have a WebView control.

I would be disappointed if this problem of event listeners forces me to use modal box.
because there would be no interest. Rhino has a script dialog and adding a document to the file can be done with a text file in the Rhino file directory.

Thank you.
jmv

Another example: I have a mouse with several buttons. When I click on the back button in the webview. This is the 3D viewport that changes.

[MAJ] I have test the editor in a Eto modal dialog. The keys: Ctrl+C/V/X, Tab, Enter work but no directional (up, down, left, right)…

Thank you Dale! At the time, I had not yet measured the usefulness of your answer …