相对窗口定位的未来

随着新兴的显示服务器技术的发展,工具包有时需要调整其实现所提供功能的方式。其中一个需要调整的功能是如何让 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 (),它接受一组参数来描述应用程序希望如何将其窗口放置在相对于某个父表面的位置。它需要:

  • 一个 transient-for 窗口

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

  • 一个矩形锚点重力

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

  • 一个窗口锚点重力

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

  • 一个锚点提示

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

  • 一个矩形锚点偏移量

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

通过让 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 实现正在进行中。

请转到错误以查看有关将来如何放置菜单的所有详细信息。

gnome-sponsored-badge-shadow