Skip to content

Commit

Permalink
fix #33 canvas keyboard initial(panda3d) and regain(pygame) focus
Browse files Browse the repository at this point in the history
  • Loading branch information
pmp-p committed Sep 25, 2023
1 parent 8a7cdd8 commit e122389
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 34 deletions.
12 changes: 7 additions & 5 deletions pygbag/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
""" packager+server for pygbag wasm loader """

import sys

# some Linux distro are stuck in the past. Better safe than sorry
sys.stdout.reconfigure(encoding='utf-8')

from pathlib import Path
Expand All @@ -25,13 +27,15 @@
sys.path.append(str(Path(__file__).parent / "support/cross"))


# WaPy=>CPython compat

import builtins
# WaPy<=>CPython compat

try:
# embed builtin module handles I/O on wasm
import embed
# aio function implemented only on stackless WaPy
sched_yield
except:
import builtins
builtins.sched_yield = lambda: None

import sys, traceback
Expand All @@ -57,5 +61,3 @@ def CSI(*argv):
ESC(f"[{arg}")


builtins.ESC = ESC
builtins.CSI = CSI
11 changes: 9 additions & 2 deletions pygbag/support/cross/__EMSCRIPTEN__.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,16 @@ class EventTarget:
events = []

def addEventListener(self, host, type, listener, options=None, useCapture=None):
cli = self.clients.setdefault(type, [])
cli = self.__class__.clients.setdefault(type, [])
cli.append(listener)

def build(self, evt_name, jsondata):
self.events.append([evt_name, json.loads(jsondata)])
try:
self.__class__.events.append([evt_name, json.loads(jsondata.strip('"'))])
except Exception as e:
sys.print_exception(e)
print(jsondata)


# def dispatchEvent
async def rpc(self, method, *argv):
Expand All @@ -170,6 +175,8 @@ async def rpc(self, method, *argv):
else:
print(f"RPC not found: {method}{argv}")

# This is a green thread handling events from js -> python

async def process(self):
import inspect
from types import SimpleNamespace
Expand Down
8 changes: 7 additions & 1 deletion pygbag/support/cross/aio/pep0723.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ async def async_repos():
if repo not in Config.pkg_repolist:
Config.pkg_repolist.append(repo)

if not aio.cross.simulator:
if window.location.href.startswith('https://pmp-p.ddns.net/pygbag'):
print(" =============== REDIRECTION TO DEV HOST ================ ")
for idx, repo in enumerate(PyConfig.pkg_repolist):
repo["-CDN-"] = "https://pmp-p.ddns.net/archives/repo/"

if Config.dev_mode > 0:
for idx, repo in enumerate(Config.pkg_repolist):
try:
Expand Down Expand Up @@ -201,7 +207,7 @@ async def pip_install(pkg, sconf={}):
wheel_pkg, wheel_hash = wheel_url.rsplit("/", 1)[-1].split("#", 1)
await install_pkg(sconf, wheel_url, wheel_pkg)
except:
print("ERROR", wheel_url)
print("INVALID", pkg, 'from',wheel_url)


async def parse_code(code, env):
Expand Down
40 changes: 31 additions & 9 deletions pygbag/support/pythonrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,11 +629,11 @@ async def preload_code(cls, code, callback=None, hint=""):
DBG(f"628: aio.pep0723.check_list {env=}")
deps = await aio.pep0723.parse_code(code, env)
DBG(f"629: aio.pep0723.pip_install {deps=}")

for dep in deps:
await aio.pep0723.pip_install(dep)

else: # sim use a local folder venv model


await aio.pep0723.check_list(code=code, filename=None)


Expand Down Expand Up @@ -909,7 +909,7 @@ def browser_open_new_tab(url):

def browser_open_file(target=None, accept="*"):
if target:
platform.EventTarget.addEventListener("upload", target)
platform.EventTarget.addEventListener(window, "upload", target)
platform.window.dlg_multifile.click()

webbrowser.open_file = browser_open_file
Expand Down Expand Up @@ -1274,15 +1274,17 @@ async def async_imports_init(cls):
async with platform.fopen(Path(cdn) / cls.repodata) as source:
cls.repos.append(json.loads(source.read()))

# print(json.dumps(cls.repos[0]["packages"], sort_keys=True, indent=4))

DBG("referenced packages :", len(cls.repos[0]["packages"]))

if not len(PyConfig.pkg_repolist):
await cls.async_repos()

# print("1117: remapping ?", PyConfig.dev_mode)
if PyConfig.pygbag > 0:
if window.location.href.startswith('https://pmp-p.ddns.net/pygbag/'):
print(" =============== REDIRECTION TO DEV HOST ================ ")
for idx, repo in enumerate(PyConfig.pkg_repolist):
repo["-CDN-"] = "https://pmp-p.ddns.net/archives/repo/"
elif PyConfig.pygbag > 0:
# if PyConfig.pygbag > 0:
for idx, repo in enumerate(PyConfig.pkg_repolist):
DBG("1264:", repo["-CDN-"], "REMAPPED TO", PyConfig.pkg_indexes[-1])
repo["-CDN-"] = PyConfig.pkg_indexes[-1]
Expand Down Expand Up @@ -1616,11 +1618,31 @@ def patch_panda3d_showbase():
import panda3d.core
from direct.showbase.ShowBase import ShowBase

print("panda3d: apply model path patch")
print(f"panda3d: apply model path {os.getcwd()} patch")
panda3d.core.get_model_path().append_directory(os.getcwd())
panda3d.core.loadPrcFileData("", "win-size 1024 600")
panda3d.core.loadPrcFileData("", "support-threads #f")
panda3d.core.loadPrcFileData("", "textures-power-2 down")
panda3d.core.loadPrcFileData("", "textures-square down")

def run(*argv, **env):
print("ShowBase.run patched")
print("ShowBase.run patched to launch asyncio.run(main())")
import direct.task.TaskManagerGlobal
async def main():
try:
print('1633: auto resizing')
platform.window.window_resize()
except:
...
while not asyncio.get_running_loop().is_closed():
try:
direct.task.TaskManagerGlobal.taskMgr.step()
except SystemExit:
print('87: Panda3D stopped',file= sys.stderr)
break
# go to host
await asyncio.sleep(0)
asyncio.run(main())

print("panda3d: apply ShowBase.run patch")
ShowBase.run = run
Expand Down
11 changes: 11 additions & 0 deletions scripts/build-loader.sh
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ done

echo CPY_CFLAGS=$CPY_CFLAGS

#\
# -I/opt/python-wasm-sdk/emsdk/upstream/emscripten/cache/sysroot/include/freetype2 -lfreetype\
# -lopenal \
#\




if emcc -fPIC -std=gnu99 -D__PYDK__=1 -DNDEBUG $CPY_CFLAGS $CF_SDL $CPOPTS \
-c -fwrapv -Wall -Werror=implicit-function-declaration -fvisibility=hidden\
-I${PYDIR}/internal -I${PYDIR} -I./support -DPy_BUILD_CORE\
Expand Down Expand Up @@ -241,8 +249,11 @@ then

#LDFLAGS="$LD_VENDOR -sUSE_GLFW=3 -sUSE_WEBGL2 -sMIN_WEBGL_VERSION=2 -sOFFSCREENCANVAS_SUPPORT=1 -sFULL_ES2 -sFULL_ES3"
LDFLAGS="$LD_SDL2"

LDFLAGS="-sUSE_GLFW=3 -sUSE_WEBGL2 -sMIN_WEBGL_VERSION=2 -sOFFSCREENCANVAS_SUPPORT=1 -sFULL_ES2 -sFULL_ES3"

# -sUSE_FREETYPE -sUSE_HARFBUZZ"


if echo ${PYBUILD}|grep -q 10$
then
Expand Down
65 changes: 49 additions & 16 deletions static/pythons.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,15 +635,11 @@ console.warn("TODO: user defined canvas")
}
vm.canvas3d = canvas3d

/*

canvas.addEventListener("click", MM.focus_handler)
/*
function event_canvas_regain(event) {
console.log("entering canvas")
canvas.focus();
}
canvas.addEventListener('mouseenter', event_canvas_regain, false);
function event_fullscreen(event){
if (!event.target.hasAttribute('fullscreen')) return;
Expand Down Expand Up @@ -1015,14 +1011,46 @@ function feat_stdout() {
// TODO make a queue, python is not always ready to receive those events
// right after page load

function feat_lifecycle() {
window.addEventListener("focus", function(e){
queue_event("focus", e )
})

window.addEventListener("blur", function(e){
queue_event("blur", e )
})
function focus_handler(ev) {
if (ev.type == "click") {
canvas.removeEventListener("click", MM.focus_handler)
canvas.focus()
return
}

if (ev.type == "mouseenter") {
canvas.focus()
console.log("canvas focus set")
canvas.removeEventListener("mouseenter", MM.focus_handler)
return
}

if (ev.type == "focus") {
queue_event("focus", ev )
console.log("focus set")
canvas.focus()
return
}

// for autofocus
if (ev.type == "blur") {
// remove initial focuser that may still be there
try {
canvas.removeEventListener("click", MM.focus_handler)
} catch (x ) {}

canvas.addEventListener("click", MM.focus_handler)
canvas.addEventListener("mouseenter", MM.focus_handler)
queue_event("blur", ev )
return
}
}


function feat_lifecycle() {
window.addEventListener("focus", MM.focus_handler)
window.addEventListener("blur", MM.focus_handler)

if (!vm.config.can_close) {
window.onbeforeunload = function() {
Expand All @@ -1033,6 +1061,7 @@ function feat_lifecycle() {
}
}


function feat_snd() {
// to set user media engagement status and possibly make it blocking
MM.UME = !vm.config.ume_block
Expand Down Expand Up @@ -1092,9 +1121,13 @@ function download(diskfile, filename) {





window.MM = { tracks : 0, UME : true, download : download, camera : {} }
window.MM = {
tracks : 0,
UME : true,
download : download,
focus_handler : focus_handler,
camera : {}
}

async function media_prepare(trackid) {
const track = MM[trackid]
Expand Down
19 changes: 18 additions & 1 deletion support/__EMSCRIPTEN__.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,11 @@ embed_webgl(PyObject *self, PyObject *args, PyObject *kwds)

PyStatus status;

#if defined(FT)
#include <freetype2/ft2build.h>
#include FT_FREETYPE_H
#endif


int
main(int argc, char **argv)
Expand Down Expand Up @@ -870,7 +875,19 @@ EM_ASM({


PyRun_SimpleString("import sys, os, json, builtins, shutil, time");
//PyRun_SimpleString("import universal;print('HPy init done')");
//PyRun_SimpleString("import hpy;import hpy.universal;print('HPy init done')");
#if defined(FT)
int error;

FT_Library library;
error = FT_Init_FreeType(&library);
if (error) {
printf("FT error %d\n", error);
} else {
puts(" @@@@@@@@@@@@@@@@@@@@@ FT OK @@@@@@@@@@@@@@@@@@@@");
}
#endif

#if SDL2
// SDL2 basic init
{
Expand Down

0 comments on commit e122389

Please sign in to comment.