Skip to content

组件方法速查 ​

用法总述(两种写法)见 README.md;所有类型经 @yue 引用。

通用约定:

  • 除单独说明外,所有 make 均有可选参数 style : Array[(String, &StyVal)] —— 单个数组混装数值(Double)与字符串值 (创建即应用的样式键值对),下表不再重复列出。
  • on_* 为回调注册方法。

窗口 Window ​

moonbit
let win = @yue.Window::make(
                title="主窗口",
                size=Some((960.0, 640.0)),
                center=true)
win.on_close(fn(_w) { @yue.quit() })
win.set_content(content_view)

Window::make 入参(无 style,窗口没有父布局):

参数类型默认说明
titleString""标题
size(Double, Double)?None内容区尺寸(宽, 高)
on_close(Window) -> Unit空操作关闭回调
centerBoolfalse创建后居中

常用方法:

方法用途
set_title(t)设标题
set_content(v)设内容视图
set_content_size(w, h) / get_content_size()设 / 读内容区尺寸
center() / activate()居中 / 激活到前台
maximize() / unmaximize() / is_maximized()最大化
set_fullscreen(b) / is_fullscreen()全屏
set_always_on_top(b)置顶
set_resizable(b) / is_resizable()可缩放
set_maximizable(b) / set_minimizable(b)标题栏按钮开关
set_has_shadow(b) / has_shadow()窗口阴影
set_menubar(mb)挂菜单条
on_close(fn(_w))关闭回调
set_should_close(fn() -> Bool)返回 false 拦截关闭

Window::new_with_options 入参(无边框 / 透明 / 浮层窗口):

参数类型默认说明
frameBooltruefalse 为无边框
transparentBoolfalse透明背景
no_activateBoolfalse不抢焦点(浮层 / 面板类窗口)

容器 Container ​

moonbit
let col = @yue.Container::make(style=[("padding", 12.0)])
col.add_child(child)

入参只有 style(见文首)。默认 flexDirection=column、 alignItems=stretch,水平排列在 style 里传 ("flexDirection", "row"); 键的解析规则见 docs/layout.md。

方法用途
add_child(v)添加子视图(任何 ViewLike)
on_draw(fn(painter))自绘

标签 Label ​

moonbit
let l = @yue.Label::make("文本", style=[("color", "#356AA0")])
l.set_text("新文本")
参数类型默认说明
textString必填初始文本
方法用途
set_text(t)改文本

按钮 Button(含复选框 / 单选框) ​

moonbit
let b = @yue.Button::make("确定", on_click=fn() { ... })
let c = @yue.Button::make("启用", button_type=Checkbox, checked=false,
                          on_click=fn() { ... })   // 回调里用 is_checked() 读状态
let r = @yue.Button::make("主题甲", button_type=Radio, checked=true, on_click=...)
b.set_title("新标题")
参数类型默认说明
titleString必填按钮文本
button_typeButtonTypeNormalNormal / Checkbox / Radio
on_click() -> Unit空操作点击回调
checkedBoolfalse初始勾选(Checkbox / Radio)

同一父容器内的 Radio 自动互斥;初始回调与双通知见文末「固有坑」。

方法用途
set_title(t)改文本
is_checked() / set_checked(b)读 / 设勾选
on_click(fn())点击回调

单行输入 Entry ​

moonbit
let e = @yue.Entry::make(text="预填", entry_type=Password)
e.on_activate(fn() { check(e.get_text()) })
参数类型默认说明
textString""初始文本
entry_typeEntryTypeNormalNormal / Password
width_charsInt-1初始宽度(字符数;-1 为不限制)
on_activate() -> Unit空操作回车回调(不带参数,取文本用 get_text)
on_text_change() -> Unit空操作内容变化回调(同上)
方法用途
get_text() / set_text(t)读 / 设文本
on_activate(fn())回车回调
on_text_change(fn())内容变化回调

多行文本 TextEdit ​

moonbit
let t = @yue.TextEdit::make(text="正文")
t.on_text_change(fn() { sync(t.get_text()) })
参数类型默认说明
textString""初始文本
on_text_change() -> Unit空操作内容变化回调
方法用途
get_text() / set_text(t)读 / 设全文
undo() / redo() / can_undo() / can_redo()撤销重做
cut() / copy() / paste()剪贴板编辑
select_all() / select_range(start, end)选区
get_text_in_range(start, end)读区间文本
insert_text(t) / insert_text_at(t, pos)插入
delete() / delete_range(start, end)删除
get_text_bounds_height()文本实际高度(自适应高度布局用)
on_text_change(fn())内容变化回调

滑块 Slider ​

moonbit
let s = @yue.Slider::make(value=0.0, range=Some((0.0, 100.0)), step=Some(1.0))
s.on_value_change(fn() { update(s.get_value()) })
参数类型默认说明
valueDouble0.0初值
range(Double, Double)?None量程(min, max)
stepDouble?None步长
on_value_change() -> Unit空操作值变化回调(不带参数,取值用 get_value)
方法用途
get_value() / set_value(v)读 / 设当前值
set_range(min, max) / set_step(d)量程 / 步长
on_value_change(fn())值变化回调
on_sliding_complete(fn())拖动结束回调

进度条 ProgressBar ​

moonbit
let p = @yue.ProgressBar::make(value=0.43)
参数类型默认说明
valueDouble0.0初值,取值 0..1
indeterminateBoolfalse往返滚动模式
方法用途
set_value(v)设值(0..1)
set_indeterminate(b)往返滚动模式

选择器 Picker ​

moonbit
let p = @yue.Picker::make(items=["甲", "乙", "丙"], selected=0)
p.on_selection_change(fn() { refresh(p.get_selected_item_index()) })
参数类型默认说明
itemsArray[String][]选项列表
selectedInt0初始选中下标
on_selection_change() -> Unit空操作选择变化回调
方法用途
add_item(t) / remove_item_at(i) / clear()维护选项
select_item_at(i)选中
get_selected_item() / get_selected_item_index()读选中项
on_selection_change(fn())选择变化回调

组合框 ComboBox(可编辑) ​

moonbit
let c = @yue.ComboBox::make(items=["红", "绿"])
c.on_text_change(fn() { refresh(c.get_text()) })
参数类型默认说明
itemsArray[String][]选项列表
selectedInt0初始选中下标
on_selection_change() -> Unit空操作选项变化回调
on_text_change() -> Unit空操作编辑区文本变化回调
方法用途
add_item(t) / select_item_at(i) / get_selected_item()同 Picker
get_text() / set_text(t)读 / 设编辑区文本
on_selection_change(fn()) / on_text_change(fn())两个变化回调

日期 DatePicker ​

moonbit
let d = @yue.DatePicker::make(epoch=Some(1700000000L))
d.on_date_change(fn() { show(d.get_date()) })
参数类型默认说明
epochInt64?None初始日期(Unix epoch 秒)
on_date_change() -> Unit空操作日期变化回调
方法用途
get_date() / set_date(epoch_seconds)读 / 设日期(epoch 秒)
on_date_change(fn())日期变化回调

隐藏步进器等定制用 DatePicker::new_with(DatePickerOptions)。

分组 Group / 滚动 Scroll / 分隔线 Separator ​

moonbit
let g = @yue.Group::make("标题", content_view)
let sc = @yue.Scroll::make(content_view, policy=Some((Automatic, Automatic)))
let sep = @yue.Separator::make(Horizontal)   // 或 Vertical

Group::make 入参:

参数类型默认说明
titleString必填标题
contentT : ViewLike必填内容视图(内部走 set_content)

Scroll::make 入参:

参数类型默认说明
contentT : ViewLike必填内容视图
content_size(Double, Double)?None内容尺寸;不传则整页滚动跟随内容自然高度
policy(ScrollPolicy, ScrollPolicy)?None平台滚动条策略(水平, 垂直):Always / Never / Automatic;显式传入时保留平台滚动条
overlayBooltrue滚动条形态:Linux/macOS 请求平台悬浮样式;Windows 默认形态为自绘悬浮细条(overlay=false 或显式 policy 时保留平台经典条)

Separator::make 入参:orientation : Orientation = Horizontal(Horizontal / Vertical)。

方法用途
Group::set_title(t)改标题
Scroll::set_content(v)换内容
Scroll::set_content_size(w, h)显式设内容尺寸
Scroll::refresh_content_size()按当前内容重算滚动范围(内容在 set_content 之后才挂入或明显长高时调用)
Scroll::set_scroll_position(h, v)设滚动位置
Scroll::set_scrollbar_policy(h, v) / set_overlay_scrollbar(b)滚动条
Scroll::get_scroll_position_x/y() / get_max_scroll_position_x/y()读位置与最大滚动量
Scroll::on_scroll(fn() -> Bool)滚动位置变化(滚轮/拖拽/程序滚动统一触发;返回 true 拦截默认处理)

Hover 组 HoverGroup ​

组内任意位置(含全部子控件)悬停即整组进入 hover 态——子控件触发的事件同样改变组的样式。

moonbit
@declarative.hover_group(
  @declarative.vbox([ /* 卡片内容:标题 / 按钮 / 输入框等 */ ], style=[("padding", 14.0)]),
  radius=8.0,
  on_change=fn(h, host) {
    // 底色高亮已内置;光标等额外反馈在回调里对 host 应用
    @yue.View::set_cursor(host, @yue.Cursor::new(if h { @yue.Hand } else { @yue.Default }))
  },
)
参数类型默认说明
childNode必填组内容
hover_bg / base_bgString主题 fill_hover / 空(透明)悬停 / 常态底色(自绘)
radiusDouble0底色圆角
on_change(Bool, Container) -> Unit空函数hover 态翻转时回调(仅变化时),携带组容器
style数组[]组容器布局样式

判定机制是指针位置轮询(100ms,读全局指针坐标与组屏幕矩形比对),不依赖容器的 enter/leave——GTK 下子容器/原生控件的事件窗口会独占指针事件,容器层收不到 enter;Windows 下同一机制工作,行为跨平台一致。

悬浮滚动条 OverlayScroll ​

Windows 上 scroll() 的默认形态(overlay=true 且未显式 policy)即走这条自绘悬浮细条;本组件是其显式选用入口——需要在 Linux/macOS 上使用同款自绘悬浮细条(替代平台悬浮样式)时采用,三平台形态统一。行为:隐藏平台滚动条,自绘主题色细条叠在内容右缘——滚动/悬停浮现,停顿约 1 秒两级渐隐,可沿轨道拖拽,窄条上滚轮转发给内容滚动。

独立使用(内容已是 Node 时):

moonbit
@declarative.overlay_scroll(
  @declarative.vbox([@declarative.label("第 1 行"), /* … */]),
  style=[("height", 180.0)],   // 容器样式;高度由外层布局或显式给定
)
参数类型默认说明
contentNode必填滚动内容(声明式节点)
style数组[]外层容器样式
handle(Scroll) -> Unit空函数拿内部 Scroll 做程序化滚动

页签 Tab ​

moonbit
let t = @yue.Tab::make(pages=[("第一页", page1), ("第二页", page2)])
t.on_selected_page_change(fn() { switch_to(t.get_selected_page_index()) })
参数类型默认说明
pagesArray[(String, Container)][]页标题与页内容(每页通常一个 Container)
on_change() -> Unit空操作切页回调
方法用途
add_page(title, v) / remove_page(v)维护页
select_page_at(i) / get_selected_page_index() / page_count()选中与查询
on_selected_page_change(fn())切页回调

页内容器是独立 yoga 子树的根;声明式建页见 docs/declarative.md 的 tab 节点。

表格 Table ​

moonbit
let t = @yue.Table::new()
t.add_column_text("姓名", 120)
t.add_column_checkbox("启用", 60)
t.set_model(my_model, column_count=2)   // 模型见下

列类型:add_column_text(title, width) / add_column_edit(title, width)(编辑结果经 set_value 回写模型)/ add_column_checkbox(title, width)(切换经 set_value 回写)/ add_column_custom(title, width, draw)(draw 收 Painter、单元格矩形与模型给出的 ColorText 文本/颜色,逐格自绘)。完整列选项用 add_column_with_options(title, ColumnOptions)。

数据模型走 MoonBit trait 桥,行数再大也只按需取数:

moonbit
trait TableModel {
  fn row_count(Self) -> Int
  fn get_value(Self, column : Int, row : Int) -> TableValue   // Str / Flag / ColorText
  fn set_value(Self, column : Int, row : Int, value : TableValue) -> Unit
}
方法用途
set_model(m, column_count)挂数据模型
on_row_activate(fn(row)) / on_selection_change(fn()) / on_toggle_checkbox(fn(column, row))行激活 / 选中变化 / 勾选切换
enable_multiple_selection(b) / select_row(i) / get_selected_row()多选与选中行
set_has_border(b)边框
notify_row_insertion(i) / notify_row_deletion(i) / notify_value_change(row, col)模型变更后刷新三件套

画布与图片 ​

任意视图绘制:

moonbit
view.on_draw(fn(painter) {
  painter.set_fill_color("#FF8800")
  painter.fill_rect(0.0, 0.0, 80.0, 80.0)
  painter.set_blend_mode(@yue.Multiply)   // 25 种混合模式
})

Painter 常用方法:

方法用途
set_fill_color(hex) / set_stroke_color(hex)颜色
fill_rect / stroke_rect / clip_rect(x, y, w, h)矩形绘制 / 裁剪
begin_path / close_path / move_to / line_to / arc / bezier_curve_to路径
fill() / stroke()提交路径
save() / restore() / translate / scale / rotate变换
draw_text(...) / draw_attributed_text(...)文本
draw_image(...) / draw_image_from_rect(...)图片
draw_canvas(...) / draw_canvas_from_rect(...)离屏画布
set_blend_mode(m)混合模式(BlendMode)

图片与离屏位图:

moonbit
let img = @yue.Image::new_from_file("a.png")
let slot = @yue.ImageSlot::new()   // 显示图片的控件
slot.set(Some(img))
API用途
Image::new_from_file(path) / new_from_png(bytes, scale?)加载
img.resize(w, h, scale?) / get_width() / get_height()缩放与尺寸
img.write_to_file(format, path)导出
img.is_empty() / get_scale_factor()状态
Canvas::new(w, h) + get_painter()离屏位图
ImageSlot::new() + set(img?) / get()图片显示控件

富文本:

moonbit
let at = @yue.AttributedText::new("一段文本", wrap=true, ellipsis=false)
at.set_color_for("#FF0000", 0, 2)
API用途
AttributedText::new(text, align?, valign?, wrap?, ellipsis?)创建
set_font_for(font, start, end) / set_color_for(hex, start, end)按区间设属性(三平台一致)
set_font(f) / set_color(hex) / set_text / set_format全文属性
get_bounds_for(w, h)布局包围盒
Font::new(name, size, weight?, style?)字体

动图 GifPlayer ​

moonbit
let g = @yue.GifPlayer::make(image=Some(img))
g.set_animating(true)
参数类型默认说明
imageImage?None初始图片(GIF 动图)
scaleImageScaleDown缩放策略:None / Fill / Down / UpOrDown
方法用途
set_image(img)换图片
set_scale(s) / get_scale()缩放策略
set_animating(b) / is_animating()播放 / 暂停
is_playing() / stop_animation_timer()播放状态 / 停止

浏览器 Browser ​

moonbit
// Browser 在独立包 yue/browser(moon.pkg import "NoahLiu/moonbit-libyue/yue/browser")
let b = @browser.Browser::make(url="https://example.com")   // 或 html="<h1>本地</h1>"
参数类型默认说明
urlString""加载的地址
htmlString""加载的 HTML;url 与 html 都给时以 url 为准
方法用途
load_url(u) / load_html(html, base_url?)加载
get_url() / get_title() / reload() / stop()当前地址 / 页面标题 / 重载 / 停止
go_back() / go_forward() / can_go_back() / can_go_forward()导航
is_loading()加载状态
set_user_agent(s)UA
execute_javascript(code) / execute_javascript_with_result(code, fn(ok, json))执行 JS;后者异步取回结果(ok=成功,json 为结果 JSON 文本)
add_raw_binding(name, fn(json)) / remove_binding(name) / has_bindings()JS↔原生绑定(网页调 name(...) 时收到 JSON 参数文本)
register_protocol(scheme, fn(url) -> (mime, content)?)自定义协议(返回 None 拒绝)
unregister_protocol(scheme)注销协议
get_cookies_for_url(url, fn(cookies))查 Cookie
on_change_loading / on_update_title / on_update_command / on_commit_navigation / on_finish_navigation事件

定制选项用 Browser::new_with_options(BrowserOptions)。

0.5.0 起 Browser 迁入独立包 NoahLiu/moonbit-libyue/yue/browser(API 不变,@browser.Browser 改 @browser.Browser);未 import 该包的程序不再链接 WebKit/WebView2。

剪贴板 Clipboard ​

moonbit
let clip = @yue.Clipboard::get()
clip.set_text("文本")
方法用途
Clipboard::get()默认剪贴板
set_text(t) / get_text()文本
set_data(kind, t) / get_data(kind) / set_data_image(img)结构化数据
clear()清空

通知 Notification / 通知中心 ​

moonbit
let n = @yue.Notification::new()
n.set_title("标题"); n.set_body("正文")
n.show()
方法用途
set_title(t) / set_body(s)内容
set_silent(b)静默
set_actions([(id, 标题)])按钮(配合 NotificationCenter 的 action 回调)
show()发送(Linux 必须经此,见 docs/adaptation.md)
close()关闭
NotificationCenter::get() + add(n)经通知中心发送

消息框 MessageBox ​

moonbit
let box = @yue.MessageBox::new(Information)
box.add_button("好", 1)
box.on_response(fn(response) { ... })
box.show_for_window(win)
方法用途
MessageBox::new(type_)类型(MessageBoxType)
set_title / set_text / set_informative_text文本
add_button(title, response)自定义按钮
on_response(fn(response))按钮响应(response 为按钮编号)
show() / show_for_window(win) / close()弹出(模态)/ 关闭

文件对话框 FileDialog ​

moonbit
let fd = @yue.FileDialog::new_open()
fd.set_filters("图片:png,jpg|全部:*")
if fd.run_for_window(win) { fd.get_result() }
方法用途
new_open() / new_save()打开 / 保存
set_filters("描述:扩展1,扩展2|描述2:扩展3")过滤器(* 匹配全部)
set_folder(path) / set_filename(name)初始目录 / 文件名
set_options(FILE_OPTION_PICK_FOLDERS | MULTI_SELECT | SHOW_HIDDEN)选项位组合
run_for_window(win) -> Bool模态运行
get_result()结果路径

文件读写:read_text_file(path) -> String?、read_binary_file(path) -> Bytes?、 write_text_file(path, content) -> Bool。

菜单 MenuBar / Menu / MenuItem ​

moonbit
let mb = @yue.MenuBar::new()
let m = mb.add_menu("文件")
m.add_label_item("打开").on_click(fn() { ... })
win.set_menubar(mb)
API用途
MenuBar::new() + add_menu(title) -> Menu菜单条
Menu::new()弹出菜单(配 popup_at(x, y))
add_label_item(t) / add_check_item(t) / add_radio_item(t)普通项 / 复选 / 单选
add_role_item(role) / add_submenu(title) / add_separator()系统角色项 / 子菜单 / 分隔线
MenuItem::on_click(fn())点击回调
MenuItem::is_checked() / set_checked(b)勾选
MenuItem::get_label() / set_label(t) / set_accelerator(s)文本与快捷键
Menu::item_count() / item_at(i);MenuBar 同遍历

托盘 Tray ​

moonbit
let tray = match @yue.Tray::new("icon.png") {
  Ok(t) => t
  Err(e) => ...   // 后端缺失或图标读取失败
}
API用途
Tray::is_supported()后端是否可用
Tray::new(icon_path) -> Result[Tray, TrayError]创建(结构化报错)
set_icon(path) / set_icon_name(name)换图标(主题名仅 Linux SNI)
set_title(t)部分平台无此概念,空操作
set_tooltip(title, body)悬浮提示(仅 Linux SNI)
on_click(fn())点击回调
set_menu(menu)挂右键菜单
remove()移除图标

Linux 推荐纯 MoonBit 的 yue/traybus 后端(Tray 统一 API 内部自动选择), 方案见 docs/tray.md。

系统集成(单实例 / 自启动 / 电源 / 会话 / 网络) ​

桌面应用的系统级能力,统一入口、统一错误风格(Err(Unsupported) 与 xxx_supported() 先行判定)。完整演示见 showcase「系统集成」页。

单实例与二次唤起 ​

moonbit
match @system.SingleInstance::acquire("org.example.MyApp") {
  Ok(Some(handle)) => {
    // 本进程是首实例,继续启动
    handle.on_activate(fn(args) {
      // 第二实例启动时收到其命令行参数:恢复 / 置前窗口
    })
  }
  Ok(None) => return  // 已有实例,唤醒已发,本进程退出
  Err(_) => ()        // 单实例不可用,调用方决定降级或退出
}
API用途
SingleInstance::acquire(app_id) -> Result[SingleInstance?, SingleInstanceError]尝试成为首实例(app_id 须为合法 DBus 总线名:点分层段、字母/下划线开头)
handle.on_activate(cb : (Array[String]) -> Unit)注册第二实例唤起回调(透传其命令行,含 argv[0])
set_instance_window_title(title)设置窗口标题(Windows 置前兜底按标题查找;运行时改标题会破坏兜底)

Linux 经会话总线声称应用专属名,Windows 经命名互斥体 + 消息窗口。

开机自启动 ​

moonbit
let auto = match @system.Autostart::new("org.example.MyApp") {
  Ok(a) => a
  Err(_) => ...   // 平台不支持(macOS 暂缓)
}
auto.enable()     // Ok 后重新登录 / 重启即拉起
auto.disable()    // 取消(幂等)
API用途
Autostart::new(app_id) -> Result[Autostart, AutostartError]句柄(app_id 同单实例约束)
Autostart::is_supported()平台是否支持
handle.is_enabled() -> Result[Bool, AutostartError]查询当前状态
handle.enable() / disable() -> Result[Unit, AutostartError]设置 / 取消(均幂等)
handle.path() -> Result[String, AutostartError]自启动项文件路径(Linux .desktop)

Linux 写 $XDG_CONFIG_HOME/autostart 的 .desktop(exe 路径取 /proc/self/exe),Windows 写 HKCU Run 键。

打开外部 ​

API用途
open_url(url) -> Result[Unit, OpenUrlError]交默认浏览器打开
reveal_in_file_manager(path) -> Result[Unit, FileManagerError]文件管理器中打开并选中(相对路径按工作目录解析;Linux FileManager1 不在线回退打开父目录,选中态丢失)

Ok 只表示已交给系统;系统侧成败不回传(浏览器是否真打开由桌面决定)。

屏幕常亮与用户空闲 ​

moonbit
match @system.KeepAwake::enable("org.example.MyApp") {
  Ok(k) => { /* 保持常亮 */ ignore(k.release()) }  // 解除
  Err(_) => ()
}
match @system.idle_seconds() {
  Ok(sec) => ...   // 自最后一次输入起的秒数(阈值判定由调用方比较)
  Err(_) => ()
}
API用途
KeepAwake::is_supported()抑制服务 / 系统能力是否可用
KeepAwake::enable(app_id) -> Result[KeepAwake, KeepAwakeError]申请常亮(Ok 只表示系统受理;是否真不熄屏由平台策略决定)
handle.release()解除(幂等)
keep_awake_active()当前是否持有常亮
idle_supported() / idle_seconds() -> Result[Double, IdleError]用户空闲秒数(Linux X11;Wayland 会话显式 Unsupported)

电量与电源事件 ​

API用途
battery_supported() / battery_query() -> Result[BatteryInfo?, PowerError]电量读数(百分比 / 充电中 / 距充满与放空秒数;无电池返回 Ok(None))
power_source() -> Result[PowerSource, PowerError]查询当前电源来源(台式机无电池,来源恒为交流在线)
power_event_supported() / on_power_source_change(cb)交直流切换事件(PowerSource::Ac / OnBattery;Windows 事件接入后置,先判 supported)
suspend_resume_supported() / on_suspend_resume(cb)休眠唤醒事件(SleepEvent::Suspending / Resuming;快速挂起唤醒可能连收两条 Resuming,库内不去抖)

Linux 电量走 UPower(系统总线),Windows 走 GetSystemPowerStatus; 休眠唤醒 Linux 走 logind PrepareForSleep,Windows 走电源广播。

锁屏解锁 ​

API用途
session_lock_supported()是否可用(锁屏工具不调 logind 的桌面收不到信号)
session_lock_watch(cb) -> Result[Unit, SystemError]订阅锁屏 / 解锁(SessionLockEvent::Locked / Unlocked;失败给结构化错误,不静默)

网络在线状态 ​

API用途
network_supported() / network_status() -> Result[NetworkStatus, NetworkError]当前在线状态(Online = 可达互联网;门户劫持按 Offline)
on_network_status_change(cb)变化事件(仅变化时派发;Linux 信号驱动,Windows 5 秒轮询)

Linux 走 NetworkManager(系统总线);首次 network_status() 同步建缓存, 最坏阻塞 1.5 秒——回调与定时器内请用事件或缓存,勿反复查询。

气泡 Popover ​

moonbit
let pop = @yue.Popover::new()
pop.set_content(view)
pop.show_relative_to(anchor_view)
方法用途
set_content(v) / set_content_size(w, h)内容与尺寸
show_relative_to(v)弹出到目标视图附近
close() / on_close(fn())关闭

全局快捷键 / 光标 / 系统 ​

API用途
register_global_shortcut("CmdOrCtrl+Shift+M", fn()) -> Int注册,返回 id;-1 为被占用(需换键)
unregister_global_shortcut(id)注销
Cursor::new(type_) + view.set_cursor(c)光标(CursorType)
Appearance::is_dark()深色外观
locale()区域
Screen::scale_factor() / primary_size()缩放 / 主屏尺寸
App::set_name(s) / App::get_name()应用名
desktop_environment()桌面环境名(诊断用)

事件(所有控件通用) ​

所有控件(ViewLike)支持:

方法用途
on_mouse_down / up / move / enter / leave鼠标
on_key_down / up键盘
on_size_changed尺寸变化
set_capture() / release_capture() / has_capture()鼠标捕获
set_style(k, v) / set_style_str(k, v)布局样式(运行期底层原语)
拖拽注册与拖放回调拖放(接收方必须注册 handle_drag_update 返回允许的操作位,缺省一律拒绝;发起方 do_drag_file_paths / do_drag_data_full 须在 on_mouse_down 回调内调用才生效;演示见 components「窗口」页)

事件载荷字段:

结构字段
MouseEventkind、button(1=左 2=右 3=中)、view_x/view_y(相对视图)、window_x/window_y(相对窗口)、screen_x/screen_y(屏幕全局坐标,右键菜单等按事件位置弹出直接用)、modifiers、timestamp
KeyEventkind、code(VKEY_* 常量)、modifiers、timestamp

modifiers 位:1=Shift 2=Ctrl 4=Alt 8=Meta;KeyEvent::describe() 输出 "Ctrl+A" 形式。键码常量表跨平台统一(Windows VK 码在事件入口归一化), 见 yue/events.mbt;连击计数用 ClickTracker(默认 400ms / 5px)。


固有坑 ​

上游 libyue 或平台行为带来,使用对应 API 前先读:

  1. Browser 导航会改写窗口标题(Windows):WebView2 宿主控件加载网页后把页面 <title> 同步为宿主窗口标题(Linux/GTK 无此现象,2026-09-19 实测)。依赖窗口 标题做窗口管理的工具会受影响,需要时用 on_update_title 自行管理标题显示。
  2. 复选/单选的初始化回调:以 checked=true 创建的 Checkbox/Radio, 挂载完成进入事件循环后会异步收到一次回调(GTK toggled 信号语义)。 回调逻辑依赖状态时先 is_checked() 判断,或容忍这次初始通知。
  3. 单选组切换是双通知:点选新项时,被取消选中的旧项也会收到一次回调 (此时旧项 is_checked()==false)。按"新选中的那个"处理业务即可。
  4. 虚拟键码是 GTK 表:VKEY_ESCAPE = 0xFF1B(65307),不是 Windows VK 值;字母与数字与 ASCII 相同。跨平台代码不要混用两张表。
  5. 样式键的解析规则:键名只保留 ASCII 字母并转小写,flexDirection / flex-direction / flexdirection 等价;数字、连字符与其他符号一律丢弃, 不要用特殊字符拼键名。键值全集见 docs/layout.md。
  6. 回调自动保活,但别在回调里同步弹事件循环:on_* 注册的闭包由库持有 强引用;Store 订阅同理。回调里调用 @yue.quit() 等终止流程后不要再 操作控件。
  7. 平台专属 API 未封装:Toolbar / Vibrant(Linux 静态库无符号)、 Button 样式与 ControlSize、Scroll 弹性、App 激活策略、Browser 缩放、 Image 模板图(macOS),ShortcutOptions / Lifetime::Reply / 通知 COMServerOptions(Windows)等,完整清单见 docs/adaptation.md。