AWTK-WIDGET-WEB-VIEW 实现笔记 (1) - 难点

server/2024/11/18 10:53:49/

webview 提供了一个跨平台的 webview 库,其接口简单,提供的例子也直观易懂。但是把它集成到 AWTK 里,还是遇到一些难题,这里记录一下,供有需要的朋友参考。

在这里插入图片描述

AWTK__5">1. 作为 AWTK 控件

webview 提供的例子都是独立的程序,要把它集成到 AWTK 里面,就需要把它封装成一个 AWTK 控件。没有找到参考的例子,只能自己摸索。

所幸 webview_create 提供了一个参数 window,让我们可以把 webview 嵌入到一个已有的窗口里面,不幸的是,不能指定 webview 在窗口的位置和大小。

webview 始终会占据整个窗口,这就需要将这个窗口,作为子窗口嵌入到主窗口中。技术上是可行的,难点在于不同平台实现方法不同。

/*** Creates a new webview instance.** @param debug Enable developer tools if supported by the backend.* @param window Optional native window handle, i.e. @c GtkWindow pointer*        @c NSWindow pointer (Cocoa) or @c HWND (Win32). If non-null,*        the webview widget is embedded into the given window, and the*        caller is expected to assume responsibility for the window as*        well as application lifecycle. If the window handle is null,*        a new window is created and both the window and application*        lifecycle are managed by the webview instance.* @remark Win32: The function also accepts a pointer to @c HWND (Win32) in the*         window parameter for backward compatibility.* @remark Win32/WebView2: @c CoInitializeEx should be called with*         @c COINIT_APARTMENTTHREADED before attempting to call this function*         with an existing window. Omitting this step may cause WebView2*         initialization to fail.* @return @c NULL on failure. Creation can fail for various reasons such*         as when required runtime dependencies are missing or when window*         creation fails.* @retval WEBVIEW_ERROR_MISSING_DEPENDENCY*         May be returned if WebView2 is unavailable on Windows.*/
WEBVIEW_API webview_t webview_create(int debug, void *window);

2. 两个主循环

webview 有自己的主循环:

/*** Runs the main loop until it's terminated.** @param w The webview instance.*/
WEBVIEW_API webview_error_t webview_run(webview_t w);

AWTK 也有自己的主循环:

/*** @method tk_run* 进入 TK 事件主循环。* @alias run* @annotation ["static", "scriptable"]** @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。*/
ret_t tk_run(void);

创建 webview 后,如果运行 webview 的主循环,就不能运行 AWTK 的主循环,反之亦然。

解决思路有几个:

    1. 两个线程,一个运行 webview 的主循环,一个运行 AWTK 的主循环。事实证明不行,两者都需要在 GUI 线程运行。
    1. webview 的主循环中,调用 AWTK 的主循环的 main_loop_step 函数。webview 提供了 webview_dispatch 用于注册回调函数,可以在回调函数中调用 AWTK 的 step 函数。但是发现 main_loop_step 里读不到窗口的输入事件,可能是 webview 的主循环把所有窗口的输入事件都处理了。
/*** Schedules a function to be invoked on the thread with the run/event loop.* Use this function e.g. to interact with the library or native handles.** @param w The webview instance.* @param fn The function to be invoked.* @param arg An optional argument passed along to the callback function.*/
WEBVIEW_API webview_error_t webview_dispatch(webview_t w,void (*fn)(webview_t w, void *arg),void *arg);
    1. AWTK 的主循环中,调用 webview 的主循环的 step 函数。但是 webview 没有提供这样的函数。
    1. 只调用 AWTK 的主循环,不管 webview 的主循环。虽然看起来有点不合理,但是实际上,在 Windows 和 MacOS 上 webview 都能正常工作,但是 Linux 上却不行。事后想来也是可以理解的,在 Windows 和 MacOS 上,AWTKwebview 都是基于原生窗口的,而 Linux 上,AWTK 基于 X11,webview 基于 GTK,两者的窗口系统不同,可能有冲突。

3. 打开新窗口的问题

在 Windows 下,将 webview 封装成 AWTK 的控件,并没有遇到太大的问题,但是点击某些链接时,webview 却打开一个新的窗口,这个窗口独立于 AWTK 窗口之外。

观察后发现,是因为这些链接的 target 属性是 _blank,webview 会打开一个新的窗口。

<a target="_blank" href="https://mall.jd.com/index-1000377260.html">ZLG 商城</a>

解决方法是,hook 所有的点击事件,如果点击的是一个链接,且 target 是 _blank,就阻止默认行为,改为在当前窗口打开。webview 提供 webview_init 函数,可以在创建 webview 时,初始化一些 js 代码,这里就可以用到。

static const char* s_hook_click ="window.addEventListener('load', function() {\n""  window.on_url_changed(window.location.href);\n""  const links = document.querySelectorAll('a[target=\"_blank\"]'); \n""  links.forEach(function(link) { \n""    link.addEventListener('click', function(event) { \n""      event.preventDefault(); \n""      window.location.href = link.href; \n""    }); \n""  }); \n""});\n";webview_init(w, s_hook_click);

后面会介绍不同的平台的实现方法。


http://www.ppmy.cn/server/142888.html

相关文章

数据处理与统计分析——04-Pandas中Series的常用方法、属性、布尔索引、运算操作

Series 概述 Series也是Pandas中的最基本的数据结构对象&#xff0c;也是DataFrame的列对象或者行对象&#xff0c;series本身也具有行索引。Series是一种类似于一维数组的对象&#xff0c;由下面两个部分组成&#xff1a; values&#xff1a;一组数据&#xff08;numpy.ndar…

Http常⻅见请求/响应头content-type内容类型讲解(笔记)

常见的 Content-Type 媒体类型 text类型&#xff1a; text/html&#xff1a;HTML格式&#xff0c;常用于网页内容。text/plain&#xff1a;纯文本格式&#xff0c;未进行任何格式化。text/xml&#xff1a;XML格式&#xff0c;表示以 XML 格式传输的数据。 image类型&#xff08…

【Nginx】反向代理Https时相关参数:

在Nginx代理后台HTTPS服务时&#xff0c;有几个关键的参数需要配置&#xff0c;以确保代理服务器能够正确地与后端服务器进行通信。一些重要参数的介绍&#xff1a; proxy_ssl_server_name&#xff1a;这个参数用于指定是否在TLS握手时通过SNI&#xff08;Server Name Indicati…

Docker基础概念

Docker基础概念 文章目录 Docker基础概念前言一、docker结构二、容器的概念 前言 为什么要学习docker?docker是现在主流流行的容器化部署服务的技术栈之一。过去传统部署服务器的时候有这些缺点 1.各种中间件&#xff0c;数据库等部署麻烦&#xff0c;版本控制难度大 2.一个服…

go+powershell脚本实现预填写管理凭据安装软件

这里使用了powershell脚本进行操作&#xff0c;使用golang进行简单的封装,实现普通用户下安装软件 powershell命令解释 $securePassword ConvertTo-SecureString "yourpasswd" -AsPlainText -Force #转换密码为SecureString格式 $credential New-Object System.Ma…

PyTorch——从入门到精通:PyTorch基础知识(张量)【PyTorch系统学习】

什么是张量&#xff08;Tensor&#xff09; ​ 张量在数学中是一个代数对象&#xff0c;描述了与矢量空间相关的代数对象集之间的多重线性映射。张量是向量和矩阵概念的推广&#xff0c;可以理解为多维数组。作为数学中的一个基本概念&#xff0c;张量有着多种类型&#xff0c;…

cache size = 16 bytes, cache line size = 4 bytes, direct-mapped cache

当 cache size 16 bytes 且 cache line size 4 bytes&#xff0c;并且是 direct-mapped cache (直接映射缓存) 时&#xff0c;可以根据以下规则配置缓存&#xff1a; 1. 基本计算 总缓存大小 16 bytes&#xff08;整个缓存可以存储的字节数&#xff09;。Cache line 大小 …

智能购物时代:AI在电商平台的革命性应用

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术已成为推动电商行业发展的关键力量。AI技术的应用不仅改变了电商的运营模式&#xff0c;还极大地丰富了消费者的购物体验。随着技术的不断进步&#xff0c;AI在电商领域的应用越来越广泛&#xff0c;从个性…