GTK+ 中的版本控制和长期稳定性承诺

本文中提出的计划取代了 2016 年 6 月在多伦多 GTK+ 黑客马拉松之后公布的计划。

本月,GTK+ 团队将发布一系列长期稳定版本中的第一个。这将使 GTK+ 更加可预测和可靠,同时不会阻碍 GTK+ 未来的改进。

这些计划是自去年 6 月在多伦多 GTK+ 黑客马拉松上制定初步计划以来,与各种利益相关者讨论的结果。

背景

自 2002 年 2.0 版本发布以来,GTK+ 一直遵循相当直接的版本控制方案

  • 主版本号表示通用 API 版本
  • 次版本号表示开发周期(如果为奇数)和稳定周期(如果为偶数)
  • 微版本号表示错误修复更新

在 GTK+ 中引入的任何 API 都保证存在到下一个主版本;在开发周期中引入的 API 保证在稳定周期开始后仍然存在。稳定周期不提供新功能或新 API。

这个方案为我们服务得很好,但它在 3.x 系列中,尤其是在与 6 个月的基于时间的开发周期结合使用时,问题变得越来越明显。在 2.x 周期中,GNOME 应用程序中的新功能被迫出现在额外的库中,因为工具包过于复杂或移动速度太慢。自 3.0 以来,GTK+ 的开发速度一直在加快。GTK+ 已被置于最前沿,每六个月都会引入新的小部件和新功能。然而,为了实现这些新的小部件和功能,工具包的一些内部结构一直处于变化的状态。

从 GNOME 的角度来看,GTK+ 一直是一个相当稳定,但不断变化的目标,因为 GNOME 开发人员和 GTK+ 开发人员可以共享反馈和建议,并快速跟上内部变化。另一方面,从社区的角度来看,关注 GTK+ 的开发更加痛苦。GNOME 项目之外的应用程序开发人员很难了解工具包中的哪些更改会影响他们的代码库。GTK+ 团队试图改进其沟通渠道,但在开发周期中发布有关更改的博客对于更广泛的 GTK+ 用户社区中的许多人来说还不够。

长期稳定的 GTK+ 版本

GTK+ 有三个主要利益相关者:希望获得功能和 API 稳定版本的应用程序开发人员;希望访问 GTK+ 开发版本以便快速引入新功能的桌面开发人员(包括大多数 GNOME 项目);以及 GTK+ 团队本身,它需要在较长的开发周期中迭代库的内部结构。

引入长期稳定的 GTK+ 版本旨在确保 GTK+ 在这些受众之间取得良好的平衡。特别是,应用程序开发人员将可以访问一个稳定的平台,该平台仍然可以访问 3.x 系列中开发的新 GTK+ 功能,例如 CSS 样式、触摸屏支持、HiDPI 显示支持、Wayland 支持、新小部件、GTK+ 检查器等等。

GTK+ 将继续发布主版本、次版本和微版本。一旦新功能稳定下来,就会发布新的主版本,预计大约每 2-3 年发布一次。当升级到新的主版本时,将删除已弃用的 API。之后,此 API 系列将被视为稳定。新的次版本可能会引入新的小部件,或更新 GDK 后端中窗口系统协议的实现,但不允许添加其他功能或主题更改。以前次版本是每六个月发布一次,现在将根据需要进行发布。我们还将至少三年内继续进行微版本发布,以修复错误和安全问题。此后的维护可能会继续,具体取决于可用的志愿者资源数量。发布周期超过三年的具有长期支持的操作系统发行版可能需要联系 GTK 团队,以建立向后移植的策略。

长期稳定系列中的更新将是 ABI 稳定的。除了这些稳定系列之外,GTK+ 开发将在半稳定的开发系列中继续进行。这些开发版本将在次版本之间包含一些 API 更改,尽管会尽可能限制更改。这是我们期望 GNOME 应用程序采用的路径,但如果其他应用程序开发人员希望访问最新功能,则可以选择此选项,但代价是每个次版本都可能需要进行一些移植工作。

虽然 GTK+ 团队保留在开发系列中更改 API 的权利,但这并不意味着整个 GTK+ API 会在每次发布时不断破坏;只有特定的,并且希望很少使用的 API 部分可能会更改,如果更改过于广泛,则很可能会延迟到下一个主要开发周期。我们将确保提前充分沟通这些更改。

新的版本控制方案

新的 GTK+ 版本控制方案是我们至今所遵循的“语义版本控制”方案的修改。一旦发布了新的主要稳定版本,开发周期就开始,我们将

  • 将 pkg-config 文件更新为新的主版本,以允许 GNOME 开发人员在开发期间以新的 API 为目标
  • 保持现有主版本号不变
  • 将次版本号更新为 90 以指示开发版本

例如,在 3.22.0 版本发布之后,在新开发周期开始时,pkg-config 文件将被称为 gtk+-4.0,并且 configure.ac 文件中的版本将设置为 3.90

每六个月将发布一个新的偶数开发版本,例如 x.90x.92x.94,直到 GTK+ 团队确信新的 API 和功能集是稳定的。这些次版本中的每一个都将提升共享库的 soname,以确保自动化工具可以拾取最终的更改并通知分发者和维护者。一旦我们达到 API 和功能集足够稳定以供更广泛的社区使用的程度,我们将发布新的主要版本 (x + 1).0 并声明 API 稳定。

一旦完成此点零版本,将创建一个新的稳定分支,并且主分支将升级到下一个点九十版本并开始新的开发周期。点九十版本将与以前的稳定版本并行安装。

gtk-versioning-scheme

3.22 将是 3.x 系列的最后一个次版本,新的版本控制方案将从 3.90 开始生效。3.22 版本在该方案中是不规则的,因为它是一个长期稳定版本,但不会收到进一步的次版本,并且没有 .0 版本号。这是一个必要的过渡步骤。

下一步

有关这些计划的更多详细信息,包括针对库开发人员和分发打包商的具体信息,将在后续的博客文章中发布。GTK+ 开发博客还将继续提供有关 GTK+ 本身技术变更的更新,以便提供有关每个即将发布的主要版本中将包含哪些更改的信息。

我们对这些计划感到兴奋,并希望它们能为 GTK+ 开创一个新时代,在这个时代,应用程序作者可以对我们的平台更有信心,同时仍然允许我们在 3.x 系列中看到的快速开发速度。

本文中提出的计划取代了 2016 年 6 月在多伦多 GTK+ 黑客马拉松之后公布的计划。

相对窗口定位的未来

随着新兴的 显示 服务器 技术的发展,工具包有时需要调整它们提供功能的实现方式。其中一组需要调整的功能是如何在 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