|
|
|
@ -9,28 +9,34 @@ using System.Collections.Generic;
|
|
|
|
|
using System.Runtime.InteropServices; |
|
|
|
|
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. */ |
|
|
|
|
internal class BrowserInput { |
|
|
|
|
internal class BrowserInput |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
private readonly Browser browser; |
|
|
|
|
|
|
|
|
|
public BrowserInput(Browser browser) { |
|
|
|
|
public BrowserInput(Browser browser) |
|
|
|
|
{ |
|
|
|
|
this.browser = browser; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool kbWasFocused = false; |
|
|
|
|
private bool mouseWasFocused = false; |
|
|
|
|
|
|
|
|
|
public void HandleInput() { |
|
|
|
|
public void HandleInput() |
|
|
|
|
{ |
|
|
|
|
browser.UIHandler.InputUpdate(); |
|
|
|
|
bool focusChanged = false; |
|
|
|
|
|
|
|
|
|
if (browser.UIHandler.MouseHasFocus || mouseWasFocused) { |
|
|
|
|
if (browser.UIHandler.MouseHasFocus || mouseWasFocused) |
|
|
|
|
{ |
|
|
|
|
HandleMouseInput(); |
|
|
|
|
} |
|
|
|
|
if (browser.UIHandler.MouseHasFocus != mouseWasFocused) { |
|
|
|
|
if (browser.UIHandler.MouseHasFocus != mouseWasFocused) |
|
|
|
|
{ |
|
|
|
|
browser.UIHandler.BrowserCursor.HasMouse = browser.UIHandler.MouseHasFocus; |
|
|
|
|
focusChanged = true; |
|
|
|
|
} |
|
|
|
@ -40,18 +46,24 @@ internal class BrowserInput {
|
|
|
|
|
|
|
|
|
|
if (kbWasFocused != browser.UIHandler.KeyboardHasFocus) focusChanged = true; |
|
|
|
|
|
|
|
|
|
if (browser.UIHandler.KeyboardHasFocus) { |
|
|
|
|
if (!kbWasFocused) { |
|
|
|
|
if (browser.UIHandler.KeyboardHasFocus) |
|
|
|
|
{ |
|
|
|
|
if (!kbWasFocused) |
|
|
|
|
{ |
|
|
|
|
BrowserNative.zfb_setFocused(browser.browserId, kbWasFocused = true); |
|
|
|
|
} |
|
|
|
|
HandleKeyInput(); |
|
|
|
|
} else { |
|
|
|
|
if (kbWasFocused) { |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (kbWasFocused) |
|
|
|
|
{ |
|
|
|
|
BrowserNative.zfb_setFocused(browser.browserId, kbWasFocused = false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (focusChanged) { |
|
|
|
|
if (focusChanged) |
|
|
|
|
{ |
|
|
|
|
browser._RaiseFocusEvent(browser.UIHandler.MouseHasFocus, browser.UIHandler.KeyboardHasFocus); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -62,24 +74,29 @@ internal class BrowserInput {
|
|
|
|
|
private MouseButton prevButtons = 0; |
|
|
|
|
private Vector2 prevPos; |
|
|
|
|
|
|
|
|
|
private class ButtonHistory { |
|
|
|
|
private class ButtonHistory |
|
|
|
|
{ |
|
|
|
|
public float lastPressTime; |
|
|
|
|
public int repeatCount; |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
if (now - lastPressTime > uiHandler.InputSettings.multiclickSpeed) { |
|
|
|
|
if (now - lastPressTime > uiHandler.InputSettings.multiclickSpeed) |
|
|
|
|
{ |
|
|
|
|
//too long ago? forget the past |
|
|
|
|
repeatCount = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (repeatCount > 0) { |
|
|
|
|
if (repeatCount > 0) |
|
|
|
|
{ |
|
|
|
|
//close enough to be a multiclick? |
|
|
|
|
var p1 = Vector2.Scale(mousePos, 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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -93,14 +110,16 @@ internal class BrowserInput {
|
|
|
|
|
|
|
|
|
|
private readonly ButtonHistory leftClickHistory = new ButtonHistory(); |
|
|
|
|
|
|
|
|
|
private void HandleMouseInput() { |
|
|
|
|
private void HandleMouseInput() |
|
|
|
|
{ |
|
|
|
|
var handler = browser.UIHandler; |
|
|
|
|
var mousePos = handler.MousePosition; |
|
|
|
|
|
|
|
|
|
var currentButtons = handler.MouseButtons; |
|
|
|
|
var mouseScroll = handler.MouseScroll; |
|
|
|
|
|
|
|
|
|
if (mousePos != prevPos) { |
|
|
|
|
if (mousePos != prevPos) |
|
|
|
|
{ |
|
|
|
|
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 rightDown = (currentButtons & MouseButton.Right) == MouseButton.Right; |
|
|
|
|
|
|
|
|
|
if (leftChange) { |
|
|
|
|
if (leftChange) |
|
|
|
|
{ |
|
|
|
|
if (leftDown) leftClickHistory.ButtonPress(mousePos, handler, browser.Size); |
|
|
|
|
BrowserNative.zfb_mouseButton( |
|
|
|
|
browser.browserId, BrowserNative.MouseButton.MBT_LEFT, leftDown, |
|
|
|
|
leftDown ? leftClickHistory.repeatCount : 0 |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
if (middleChange) { |
|
|
|
|
if (middleChange) |
|
|
|
|
{ |
|
|
|
|
//no double-clicks, to be consistent with other browsers |
|
|
|
|
BrowserNative.zfb_mouseButton( |
|
|
|
|
browser.browserId, BrowserNative.MouseButton.MBT_MIDDLE, middleDown, 1 |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
if (rightChange) { |
|
|
|
|
if (rightChange) |
|
|
|
|
{ |
|
|
|
|
//no double-clicks, to be consistent with other browsers |
|
|
|
|
BrowserNative.zfb_mouseButton( |
|
|
|
|
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. |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="mouseScroll"></param> |
|
|
|
|
private void FeedScrolling(Vector2 mouseScroll, float scrollSpeed) { |
|
|
|
|
private void FeedScrolling(Vector2 mouseScroll, float 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); |
|
|
|
|
|
|
|
|
|
//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.) |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
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 |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
BrowserNative.zfb_mouseScroll(browser.browserId, 0, (int)accumulatedScroll.y); |
|
|
|
|
accumulatedScroll.x = Mathf.Round(accumulatedScroll.x * .5f); |
|
|
|
|
accumulatedScroll.y = 0; |
|
|
|
@ -175,27 +202,32 @@ internal class BrowserInput {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void HandleKeyInput() { |
|
|
|
|
private void HandleKeyInput() |
|
|
|
|
{ |
|
|
|
|
var keyEvents = browser.UIHandler.KeyEvents; |
|
|
|
|
if (keyEvents.Count > 0) HandleKeyInput(keyEvents); |
|
|
|
|
|
|
|
|
|
if (extraEventsToInject.Count > 0) { |
|
|
|
|
if (extraEventsToInject.Count > 0) |
|
|
|
|
{ |
|
|
|
|
HandleKeyInput(extraEventsToInject); |
|
|
|
|
extraEventsToInject.Clear(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void HandleKeyInput(List<Event> keyEvents) { |
|
|
|
|
private void HandleKeyInput(List<Event> keyEvents) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
#if ZF_OSX |
|
|
|
|
ReconstructInputs(keyEvents); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
foreach (var ev in keyEvents) { |
|
|
|
|
foreach (var ev in keyEvents) |
|
|
|
|
{ |
|
|
|
|
var keyCode = KeyMappings.GetWindowsKeyCode(ev); |
|
|
|
|
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); |
|
|
|
|
else keysToReleaseOnFocusLoss.Remove(ev.keyCode); |
|
|
|
|
} |
|
|
|
@ -208,23 +240,28 @@ internal class BrowserInput {
|
|
|
|
|
|
|
|
|
|
FireCommands(ev); |
|
|
|
|
|
|
|
|
|
if (ev.character != 0 && ev.type == EventType.KeyDown) { |
|
|
|
|
if (ev.character != 0 && ev.type == EventType.KeyDown) |
|
|
|
|
{ |
|
|
|
|
#if ZF_LINUX |
|
|
|
|
//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. |
|
|
|
|
BrowserNative.zfb_keyEvent(browser.browserId, true, keyCode); |
|
|
|
|
//Thanks for being consistent, Unity. |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
Input.imeCompositionMode = IMECompositionMode.On; |
|
|
|
|
BrowserNative.zfb_characterEvent(browser.browserId, ev.character, keyCode); |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
BrowserNative.zfb_keyEvent(browser.browserId, ev.type == EventType.KeyDown, keyCode); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void HandleFocusLoss() { |
|
|
|
|
foreach (var keyCode in keysToReleaseOnFocusLoss) { |
|
|
|
|
public void HandleFocusLoss() |
|
|
|
|
{ |
|
|
|
|
foreach (var keyCode in keysToReleaseOnFocusLoss) |
|
|
|
|
{ |
|
|
|
|
//Debug.Log("Key " + keyCode + " is held, release"); |
|
|
|
|
var wCode = KeyMappings.GetWindowsKeyCode(new Event() { keyCode = keyCode }); |
|
|
|
|
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. |
|
|
|
|
*/ |
|
|
|
|
protected void FireCommands(Event ev) { |
|
|
|
|
protected void FireCommands(Event ev) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
#if ZF_OSX |
|
|
|
|
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. |
|
|
|
|
if (ev.type != EventType.KeyUp || !ev.control) return; |
|
|
|
|
|
|
|
|
|
switch (ev.keyCode) { |
|
|
|
|
switch (ev.keyCode) |
|
|
|
|
{ |
|
|
|
|
case KeyCode.A: |
|
|
|
|
browser.SendFrameCommand(BrowserNative.FrameCommand.SelectAll); |
|
|
|
|
break; |
|
|
|
|