相对窗口定位的未来

随着新兴的 显示 服务器 技术的发展,工具包有时需要调整它们实现所提供功能的方式。其中需要调整的一组功能是 GTK+ 如何定位弹出窗口,如菜单、弹出框和工具提示,以使其放置在显示器的工作区域内。

在过去,当 GTK+ 想要定位一个菜单时,它会首先查找菜单的父窗口的全局位置。然后,它会查找所有连接的显示器的工作区域。有了给定的工作区域、父窗口的全局位置以及相对于父窗口的预期菜单位置,GTK+ 会使用一个巧妙的算法来计算菜单的合理位置,以便其对用户可见。例如,如果“文件”菜单没有足够的空间在父菜单项下方弹出,则 GTK+ 会将其重新定位到父菜单项的上方。

popup-flip

由于 各种 原因,在这些新的显示服务器技术中,“全局窗口位置”的概念已从客户端中删除,这意味着我们不能再在 GTK+ 中使用我们巧妙的算法。

但我们仍然希望我们的菜单、工具提示、弹出框等对期望与之交互的用户完全可见,那么我们如何在不知道窗口定位的情况下确保这一点呢?

为了在 GTK+ 中解决这个问题,我们必须解决许多问题。

  • 定位逻辑需要移动到 GDK,同时仍然允许 GTK+ 影响菜单定位的行为,如果最初预期的位置最终位于工作区域之外。
  • 不同的 GDK 后端可能会做 不同的 事情
  • 某些类型的窗口需要知道最终的定位位置,以便它们可以调整自身的绘制方式。
  • 有些窗口只是想尽可能多地占用空间(例如,选择过多的菜单不应高于屏幕)。

去年,William Hua 和我开始 致力于 将 GTK+ 带入无全局位置菜单窗口的光明未来。在提出一组完成此工作的补丁之后,关于这样一个 API 实际看起来如何的讨论开始了。经过 200-300 条评论,我们决定应该面对面讨论这个问题。

欢迎来到多伦多的 GTK2016

在黑客节上,我们有机会坐在白板前,仔细研究不同的用例、需要解决的问题、后端如何工作,最终我们提出了一个 API。

william-draws-whiteboard(图片来源:Allison Lortie)

我们提出的 API 如下所示

在 GDK 端,我们引入了一个新函数(目前没有任何 API 稳定性保证;目前仅供 GTK+ 使用)gdk_window_move_to_rect (),它接受一组参数,描述应用程序希望其窗口如何相对于某个父表面放置。它接受

  • 一个瞬态窗口

要放置的父窗口,它相对于父窗口上的一个锚点矩形,弹出窗口或菜单通常希望相对于父窗口上的一个矩形放置,例如,右键单击上下文菜单应从单击时指针所在的像素的某个方向展开,或者文件菜单应放置在父窗口上的文件菜单项矩形下方或上方。

  • 一个矩形锚点重力

不同的弹出菜单可能希望以特定方向打开。例如,垂直菜单可能希望向右打开,而水平菜单可能希望向下打开。

  • 一个窗口锚点重力

不同的弹出菜单可能希望以不同的方式与父锚点矩形的锚点矩形对齐。例如,虽然组合框可能希望在某个方向展开,但它会希望覆盖它展开的矩形。

  • 一个锚点提示

不同的弹出菜单希望以不同的方式调整其位置;有些希望从父锚点矩形的不同方向展开,有些希望只是滑动到可见位置,有些希望调整大小,而有些希望是这三者的某种组合。

  • 一个矩形锚点偏移

偏移只是一个微调因子,用于弹出菜单相对于锚点偏移其位置的常见用例。

通过让 GTK+ 提出其希望如何定位菜单的声明式描述,我们允许 GDK 根据显示服务器系统的设计以不同的方式实现实际定位。在 Mir 上,会创建一个 MirSurfaceSpec,而在 Wayland 上,会创建一个 xdg_positioner 对象。在 X11、Windows 和 Mac OS X 上,后端可以使用可用的全局位置以及显示器工作区域,并像以前一样计算最佳位置。

但是,应用程序开发人员目前不应直接使用此 API。通常,需要创建菜单、弹出框、组合框,为此,我们引入了一组参数和辅助函数,使其非常方便。该 API 由一些新属性组成

  • GtkMenu:anchor-hints – 定位策略。
  • GtkMenu:rect-anchor-dx – 水平偏移量,用于移动窗口。
  • GtkMenu:rect-anchor-dy – 垂直偏移量,用于移动窗口。
  • GtkMenu:menu-type-hint – 窗口类型 – 这仍然是必需的,以便 X11 后端可以使窗口管理器知道正在映射哪种类型的弹出窗口。

还有一些其他函数

  • gtk_menu_popup_at_rect () – 给定设置的参数,相对于父窗口上的给定矩形弹出菜单。
  • gtk_menu_popup_at_widget () – 给定设置的参数,相对于父窗口上的给定小部件弹出菜单。
  • gtk_menu_popup_at_pointer () – 给定设置的参数,相对于用户刚点击的位置弹出菜单。

有了这些函数,自定义小部件的开发人员现在可以以可移植的方式定位弹出菜单。到目前为止,GTK+ 自己的弹出菜单已经移植为使用这些新函数。Mir 后端已经有一个基本的概念验证,并且 Wayland 实现正在进行中。

前往 bug 以查看有关如何在将来放置菜单的所有详细信息。

gnome-sponsored-badge-shadow

GTK+ 2.15.3 不稳定版本

这是通往 GTK+ 2.16 的第三个开发版本。
此版本修复了 8 个错误

  • 常规
    • 键盘快捷键处理已更改,以帮助解决长期以来关于 GTK+ 处理多个布局的方式的抱怨。GTK+ 现在仅在当前组中不存在键时才使用来自当前组之外的其他组的键。欢迎就此更改提供反馈。

阅读 原始公告 以获取更多信息和下载。

GTK+ 2.15.2 不稳定版本

这是通往 GTK+ 2.16 的第二个开发版本。
此版本修复了 4 个错误

  • GtkAction
    • 使工具项从操作中获取图标名称
    • 正确绘制单选操作的代理
    • 使最近操作的菜单代理工作
    • 避免在代理上更改操作时意外激活
    • 使派生按钮类充当代理
  • 输入法
    • 避免由于输入法的早期使用而导致的断言
  • GtkScale
    • 避免在标记绘制代码中出现段错误
  • GtkImageMenuItem
    • 添加一个属性来覆盖 show-menu-images 设置

阅读 原始公告 以获取更多信息和下载。

GTK+ 2.15.1 不稳定版本

这是通往 GTK+ 2.16 的第一个开发版本。
此版本修复了 35 个错误

  • GtkFileChooser
    • 记住文件选择器在多次调用中的大小
    • 处理在条目中输入的 uris
    • 改进自动完成,特别是对于 uris
  • GtkEntry
    • 每个小部件选择输入法的新属性“im-module”
    • 新的图标相关 API 已重命名以保持一致性
    • 为图标工具提示添加了属性和设置器
  • GtkTextView
    • 每个小部件选择输入法的新属性“im-module”
    • 新增 “paste-done” 信号,以便更好地处理异步粘贴
  • GtkScale
    • 新增 API 以添加带注释的标记:gtk_scale_add_mark。
  • GtkAction
    • 重新设计了动作和代理的交互方式,使交互更加规范、更具可扩展性,并且更适合在 Glade 等 GUI 构建器中支持。要用作代理,小部件现在必须实现 GtkActivatable 接口,并且 GtkActivatable 的实现负责将其外观与动作同步并激活该动作。所有常用作代理的小部件现在都实现了 GtkActivatable。这是一个很大的改动,并且很可能破坏 GtkAction 的一些现有用户,因此欢迎提供有关此更改造成的问题的反馈。
    • 添加了一个 “gicon” 属性,用于使用 GIcon 指定图标
  • GDK
    • 在 X11 上,GDK 现在缓存光标以避免光标主题开销
    • 用于空白光标的新光标类型:GDK_BLANK_CURSOR
  • 新的弃用
    • gtk_scale_Button_get_orientation()
    • gtk_scale_button_set_orientation()
    • gtk_action_connect_proxy()
    • gtk_action_disconnect_proxy()
    • gtk_widget_get_action()
    • gtk_action_block_activate_from()
    • gtk_action_unblock_activate_from()
    • 直接访问 “gtk-action” 对象数据
  • 与翻译人员相关的更改
    • 导航和媒体股票标签现在具有单独的消息上下文
    • 大写锁定警告字符串已更改

阅读原始公告以获取更多信息和下载。

GTK+ 2.15.0 不稳定版发布

这是通往 GTK+ 2.16 的第一个开发版本。

2.14.x 和 2.15.0 之间的更改概述

  • GtkFileChooser
    • 可选地显示文件大小
    • 必要时挂载卷
    • 选择更好的 MIME 图标
  • GtkEntry
    • 可以在条目的任一侧显示图标,这些图标可以单击、作为拖动源等
    • 可以显示进度信息
    • 除非显式设置,否则会为不可见条目选择最佳的可用占位符字符。请参阅 invisible-char-set 属性
    • 输入法在不可见条目中再次起作用
    • 不可见条目可以选择显示大写锁定警告。可以使用 caps-lock-warning 属性关闭此功能
  • GtkStatusIcon
  • GtkLinkButton
    • 尊重用户定义的工具提示
    • 具有默认的 URL 钩子
  • GtkBuilder
    • 可以构建菜单
    • 可以将加速器组与窗口关联
    • 子属性现在可以翻译,例如 GtkAssistant::page-title
  • GtkOrientable
    • 所有具有水平和垂直变体的小部件实现的新接口
    • 打印支持
    • 打印到文件可以保存到非本地文件
    • 页面渲染可以延迟到线程以避免阻塞主循环
  • GDK
    • 当大写锁定状态更改时,GdkKeymap 会发出 state-changed 信号
  • 新弃用的函数
    • gdk_window_get_toplevels(),
    • gtk_font_selection_dialog_get_apply_button(),
    • gtk_status_icon_set_tooltip(),
    • gtk_toolbar_set_orientation()
  • 与主题作者相关的更改
    • GtkMenu::arrow-placement 样式属性允许更节省空间的滚动菜单布局
    • 子菜单箭头可以相对于字体大小缩放,使用
    • GtkMenuItem::arrow-scaling 样式属性
    • 主题可以设置 GtkDialog::content-area-spacing 样式属性来更改内容区域元素之间的间距
    • GtkEntry::state-hint 样式属性可用于使 GTK+ 在绘制条目的背景时传递正确的状态
    • GtkEntry::prelight 样式属性可用于在鼠标悬停时抑制条目中图标的预亮
  • 与翻译人员相关的更改
    • GTK+ 已切换为使用双参数 C_() 宏而不是 Q_() 来处理带上下文的消息

阅读原始公告以获取更多信息,包括错误修复和下载位置。