Browse Source

能正确输入中文

master
杨栋梁 2 years ago
parent
commit
99dcb3dbca
  1. 127
      Assets/ZFBrowser/Scripts/BrowserInput.cs

127
Assets/ZFBrowser/Scripts/BrowserInput.cs

@ -9,28 +9,34 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using UnityEngine; using UnityEngine;
namespace ZenFulcrum.EmbeddedBrowser { namespace ZenFulcrum.EmbeddedBrowser
{
/** Helper class for reading data from an IUIHandler, converting it, and feeding it to the native backend. */ /** Helper class for reading data from an IUIHandler, converting it, and feeding it to the native backend. */
internal class BrowserInput { internal class BrowserInput
{
private readonly Browser browser; private readonly Browser browser;
public BrowserInput(Browser browser) { public BrowserInput(Browser browser)
{
this.browser = browser; this.browser = browser;
} }
private bool kbWasFocused = false; private bool kbWasFocused = false;
private bool mouseWasFocused = false; private bool mouseWasFocused = false;
public void HandleInput() { public void HandleInput()
{
browser.UIHandler.InputUpdate(); browser.UIHandler.InputUpdate();
bool focusChanged = false; bool focusChanged = false;
if (browser.UIHandler.MouseHasFocus || mouseWasFocused) { if (browser.UIHandler.MouseHasFocus || mouseWasFocused)
{
HandleMouseInput(); HandleMouseInput();
} }
if (browser.UIHandler.MouseHasFocus != mouseWasFocused) { if (browser.UIHandler.MouseHasFocus != mouseWasFocused)
{
browser.UIHandler.BrowserCursor.HasMouse = browser.UIHandler.MouseHasFocus; browser.UIHandler.BrowserCursor.HasMouse = browser.UIHandler.MouseHasFocus;
focusChanged = true; focusChanged = true;
} }
@ -40,18 +46,24 @@ internal class BrowserInput {
if (kbWasFocused != browser.UIHandler.KeyboardHasFocus) focusChanged = true; if (kbWasFocused != browser.UIHandler.KeyboardHasFocus) focusChanged = true;
if (browser.UIHandler.KeyboardHasFocus) { if (browser.UIHandler.KeyboardHasFocus)
if (!kbWasFocused) { {
if (!kbWasFocused)
{
BrowserNative.zfb_setFocused(browser.browserId, kbWasFocused = true); BrowserNative.zfb_setFocused(browser.browserId, kbWasFocused = true);
} }
HandleKeyInput(); HandleKeyInput();
} else { }
if (kbWasFocused) { else
{
if (kbWasFocused)
{
BrowserNative.zfb_setFocused(browser.browserId, kbWasFocused = false); BrowserNative.zfb_setFocused(browser.browserId, kbWasFocused = false);
} }
} }
if (focusChanged) { if (focusChanged)
{
browser._RaiseFocusEvent(browser.UIHandler.MouseHasFocus, browser.UIHandler.KeyboardHasFocus); browser._RaiseFocusEvent(browser.UIHandler.MouseHasFocus, browser.UIHandler.KeyboardHasFocus);
} }
} }
@ -62,24 +74,29 @@ internal class BrowserInput {
private MouseButton prevButtons = 0; private MouseButton prevButtons = 0;
private Vector2 prevPos; private Vector2 prevPos;
private class ButtonHistory { private class ButtonHistory
{
public float lastPressTime; public float lastPressTime;
public int repeatCount; public int repeatCount;
public Vector3 lastPosition; public Vector3 lastPosition;
public void ButtonPress(Vector3 mousePos, IBrowserUI uiHandler, Vector2 browserSize) { public void ButtonPress(Vector3 mousePos, IBrowserUI uiHandler, Vector2 browserSize)
{
var now = Time.realtimeSinceStartup; var now = Time.realtimeSinceStartup;
if (now - lastPressTime > uiHandler.InputSettings.multiclickSpeed) { if (now - lastPressTime > uiHandler.InputSettings.multiclickSpeed)
{
//too long ago? forget the past //too long ago? forget the past
repeatCount = 0; repeatCount = 0;
} }
if (repeatCount > 0) { if (repeatCount > 0)
{
//close enough to be a multiclick? //close enough to be a multiclick?
var p1 = Vector2.Scale(mousePos, browserSize); var p1 = Vector2.Scale(mousePos, browserSize);
var p2 = Vector2.Scale(lastPosition, browserSize); var p2 = Vector2.Scale(lastPosition, browserSize);
if (Vector2.Distance(p1, p2) > uiHandler.InputSettings.multiclickTolerance) { if (Vector2.Distance(p1, p2) > uiHandler.InputSettings.multiclickTolerance)
{
repeatCount = 0; repeatCount = 0;
} }
} }
@ -93,14 +110,16 @@ internal class BrowserInput {
private readonly ButtonHistory leftClickHistory = new ButtonHistory(); private readonly ButtonHistory leftClickHistory = new ButtonHistory();
private void HandleMouseInput() { private void HandleMouseInput()
{
var handler = browser.UIHandler; var handler = browser.UIHandler;
var mousePos = handler.MousePosition; var mousePos = handler.MousePosition;
var currentButtons = handler.MouseButtons; var currentButtons = handler.MouseButtons;
var mouseScroll = handler.MouseScroll; var mouseScroll = handler.MouseScroll;
if (mousePos != prevPos) { if (mousePos != prevPos)
{
BrowserNative.zfb_mouseMove(browser.browserId, mousePos.x, 1 - mousePos.y); BrowserNative.zfb_mouseMove(browser.browserId, mousePos.x, 1 - mousePos.y);
} }
@ -113,20 +132,23 @@ internal class BrowserInput {
var rightChange = (prevButtons & MouseButton.Right) != (currentButtons & MouseButton.Right); var rightChange = (prevButtons & MouseButton.Right) != (currentButtons & MouseButton.Right);
var rightDown = (currentButtons & MouseButton.Right) == MouseButton.Right; var rightDown = (currentButtons & MouseButton.Right) == MouseButton.Right;
if (leftChange) { if (leftChange)
{
if (leftDown) leftClickHistory.ButtonPress(mousePos, handler, browser.Size); if (leftDown) leftClickHistory.ButtonPress(mousePos, handler, browser.Size);
BrowserNative.zfb_mouseButton( BrowserNative.zfb_mouseButton(
browser.browserId, BrowserNative.MouseButton.MBT_LEFT, leftDown, browser.browserId, BrowserNative.MouseButton.MBT_LEFT, leftDown,
leftDown ? leftClickHistory.repeatCount : 0 leftDown ? leftClickHistory.repeatCount : 0
); );
} }
if (middleChange) { if (middleChange)
{
//no double-clicks, to be consistent with other browsers //no double-clicks, to be consistent with other browsers
BrowserNative.zfb_mouseButton( BrowserNative.zfb_mouseButton(
browser.browserId, BrowserNative.MouseButton.MBT_MIDDLE, middleDown, 1 browser.browserId, BrowserNative.MouseButton.MBT_MIDDLE, middleDown, 1
); );
} }
if (rightChange) { if (rightChange)
{
//no double-clicks, to be consistent with other browsers //no double-clicks, to be consistent with other browsers
BrowserNative.zfb_mouseButton( BrowserNative.zfb_mouseButton(
browser.browserId, BrowserNative.MouseButton.MBT_RIGHT, rightDown, 1 browser.browserId, BrowserNative.MouseButton.MBT_RIGHT, rightDown, 1
@ -152,20 +174,25 @@ internal class BrowserInput {
/// to prevent the backend from getting choked up and taking forever to execute the requests. /// to prevent the backend from getting choked up and taking forever to execute the requests.
/// </summary> /// </summary>
/// <param name="mouseScroll"></param> /// <param name="mouseScroll"></param>
private void FeedScrolling(Vector2 mouseScroll, float scrollSpeed) { private void FeedScrolling(Vector2 mouseScroll, float scrollSpeed)
{
accumulatedScroll += mouseScroll * scrollSpeed; accumulatedScroll += mouseScroll * scrollSpeed;
if (accumulatedScroll.sqrMagnitude != 0 && Time.realtimeSinceStartup > lastScrollEvent + maxScrollEventRate) { if (accumulatedScroll.sqrMagnitude != 0 && Time.realtimeSinceStartup > lastScrollEvent + maxScrollEventRate)
{
//Debug.Log("Do scroll: " + accumulatedScroll); //Debug.Log("Do scroll: " + accumulatedScroll);
//The backend seems to have trouble coping with horizontal AND vertical scroll. So only do one at a time. //The backend seems to have trouble coping with horizontal AND vertical scroll. So only do one at a time.
//(And if we do both at once, vertical appears to get priority and horizontal gets ignored.) //(And if we do both at once, vertical appears to get priority and horizontal gets ignored.)
if (Mathf.Abs(accumulatedScroll.x) > Mathf.Abs(accumulatedScroll.y)) { if (Mathf.Abs(accumulatedScroll.x) > Mathf.Abs(accumulatedScroll.y))
{
BrowserNative.zfb_mouseScroll(browser.browserId, (int)accumulatedScroll.x, 0); BrowserNative.zfb_mouseScroll(browser.browserId, (int)accumulatedScroll.x, 0);
accumulatedScroll.x = 0; accumulatedScroll.x = 0;
accumulatedScroll.y = Mathf.Round(accumulatedScroll.y * .5f);//reduce the thing we weren't doing so it's less likely to accumulate strange accumulatedScroll.y = Mathf.Round(accumulatedScroll.y * .5f);//reduce the thing we weren't doing so it's less likely to accumulate strange
} else { }
else
{
BrowserNative.zfb_mouseScroll(browser.browserId, 0, (int)accumulatedScroll.y); BrowserNative.zfb_mouseScroll(browser.browserId, 0, (int)accumulatedScroll.y);
accumulatedScroll.x = Mathf.Round(accumulatedScroll.x * .5f); accumulatedScroll.x = Mathf.Round(accumulatedScroll.x * .5f);
accumulatedScroll.y = 0; accumulatedScroll.y = 0;
@ -175,56 +202,66 @@ internal class BrowserInput {
} }
} }
private void HandleKeyInput() { private void HandleKeyInput()
{
var keyEvents = browser.UIHandler.KeyEvents; var keyEvents = browser.UIHandler.KeyEvents;
if (keyEvents.Count > 0) HandleKeyInput(keyEvents); if (keyEvents.Count > 0) HandleKeyInput(keyEvents);
if (extraEventsToInject.Count > 0) { if (extraEventsToInject.Count > 0)
{
HandleKeyInput(extraEventsToInject); HandleKeyInput(extraEventsToInject);
extraEventsToInject.Clear(); extraEventsToInject.Clear();
} }
} }
private void HandleKeyInput(List<Event> keyEvents) { private void HandleKeyInput(List<Event> keyEvents)
{
#if ZF_OSX #if ZF_OSX
ReconstructInputs(keyEvents); ReconstructInputs(keyEvents);
#endif #endif
foreach (var ev in keyEvents) { foreach (var ev in keyEvents)
{
var keyCode = KeyMappings.GetWindowsKeyCode(ev); var keyCode = KeyMappings.GetWindowsKeyCode(ev);
if (ev.character == '\n') ev.character = '\r';//'cuz that's what Chromium expects if (ev.character == '\n') ev.character = '\r';//'cuz that's what Chromium expects
if (ev.character == 0) { if (ev.character == 0)
{
if (ev.type == EventType.KeyDown) keysToReleaseOnFocusLoss.Add(ev.keyCode); if (ev.type == EventType.KeyDown) keysToReleaseOnFocusLoss.Add(ev.keyCode);
else keysToReleaseOnFocusLoss.Remove(ev.keyCode); else keysToReleaseOnFocusLoss.Remove(ev.keyCode);
} }
// if (false) { // if (false) {
// if (ev.character != 0) Debug.Log("k >>> " + ev.character); // if (ev.character != 0) Debug.Log("k >>> " + ev.character);
// else if (ev.type == EventType.KeyUp) Debug.Log("k ^^^ " + ev.keyCode); // else if (ev.type == EventType.KeyUp) Debug.Log("k ^^^ " + ev.keyCode);
// else if (ev.type == EventType.KeyDown) Debug.Log("k vvv " + ev.keyCode); // else if (ev.type == EventType.KeyDown) Debug.Log("k vvv " + ev.keyCode);
// } // }
FireCommands(ev); FireCommands(ev);
if (ev.character != 0 && ev.type == EventType.KeyDown) { if (ev.character != 0 && ev.type == EventType.KeyDown)
{
#if ZF_LINUX #if ZF_LINUX
//It seems, on Linux, we don't get keydown, keypress, keyup, we just get a keypress, keyup. //It seems, on Linux, we don't get keydown, keypress, keyup, we just get a keypress, keyup.
//So, fire the keydown just before the keypress. //So, fire the keydown just before the keypress.
BrowserNative.zfb_keyEvent(browser.browserId, true, keyCode); BrowserNative.zfb_keyEvent(browser.browserId, true, keyCode);
//Thanks for being consistent, Unity. //Thanks for being consistent, Unity.
#endif #endif
Input.imeCompositionMode = IMECompositionMode.On;
BrowserNative.zfb_characterEvent(browser.browserId, ev.character, keyCode); BrowserNative.zfb_characterEvent(browser.browserId, ev.character, keyCode);
} else { }
else
{
BrowserNative.zfb_keyEvent(browser.browserId, ev.type == EventType.KeyDown, keyCode); BrowserNative.zfb_keyEvent(browser.browserId, ev.type == EventType.KeyDown, keyCode);
} }
} }
} }
public void HandleFocusLoss() { public void HandleFocusLoss()
foreach (var keyCode in keysToReleaseOnFocusLoss) { {
foreach (var keyCode in keysToReleaseOnFocusLoss)
{
//Debug.Log("Key " + keyCode + " is held, release"); //Debug.Log("Key " + keyCode + " is held, release");
var wCode = KeyMappings.GetWindowsKeyCode(new Event() { keyCode = keyCode }); var wCode = KeyMappings.GetWindowsKeyCode(new Event() { keyCode = keyCode });
BrowserNative.zfb_keyEvent(browser.browserId, false, wCode); BrowserNative.zfb_keyEvent(browser.browserId, false, wCode);
@ -289,7 +326,8 @@ internal class BrowserInput {
* *
* Also, ctrl+A stopped working with CEF at some point on Windows. * Also, ctrl+A stopped working with CEF at some point on Windows.
*/ */
protected void FireCommands(Event ev) { protected void FireCommands(Event ev)
{
#if ZF_OSX #if ZF_OSX
if (ev.type != EventType.KeyDown || ev.character != 0 || !ev.command) return; if (ev.type != EventType.KeyDown || ev.character != 0 || !ev.command) return;
@ -322,7 +360,8 @@ internal class BrowserInput {
//mmm, yeah. I guess Unity doesn't send us the keydown on a ctrl+a keystroke anymore. //mmm, yeah. I guess Unity doesn't send us the keydown on a ctrl+a keystroke anymore.
if (ev.type != EventType.KeyUp || !ev.control) return; if (ev.type != EventType.KeyUp || !ev.control) return;
switch (ev.keyCode) { switch (ev.keyCode)
{
case KeyCode.A: case KeyCode.A:
browser.SendFrameCommand(BrowserNative.FrameCommand.SelectAll); browser.SendFrameCommand(BrowserNative.FrameCommand.SelectAll);
break; break;
@ -330,6 +369,6 @@ internal class BrowserInput {
#endif #endif
} }
} }
} }

Loading…
Cancel
Save