GTK 3.96.0

本周,我们发布了 GTK 3.96.0。同样,距离上次发布已经有一段时间了,因此值得总结一下此版本中的新功能。这里的内容实在太多了,无法全部涵盖,因此这篇文章只会重点介绍最重要的更改。

此版本是我们迈向 GTK 4 的又一个里程碑。尽管仍有一些未完成的事情,但此版本更接近我们希望通过 GTK 4 实现的目标。

GSK

GSK 已经进行了许多错误修复和新的测试,使用新的调试工具 gtk4-node-editor 可以更容易地进行这些测试。它可以加载和显示序列化的渲染节点树,例如从 GTK 检查器保存的渲染节点树,并比较不同渲染器的输出。

3D 转换支持已提升到我们可以进行如下面的立方体旋转动画转换的水平。

GDK

向 Wayland 风格的 API 迁移的趋势仍在继续,更多仅限 X11 的 API 被移动到 X11 后端或直接删除。子表面和全局坐标的使用已大大减少,但这项工作尚未完成。

拖放的重构也已继续,引入了 GdkDragGdkDrop 对象。此重构的 GTK 部分仍未完成。

事件已简化,现在仅用于输入。其他事件已被 GdkSurface 上的信号和属性替换。详细来说,暴露事件已被 ::render 信号替换,配置事件已被 ::size-changed 信号替换。映射事件已被 :mapped 属性替换,gdk_event_handler_set() 已被 ::event 信号替换。

Wayland 后端已获得对 GtkSettings 的设置门户的支持,并使用 text-input-unstable-v3 协议来支持其输入法。

GTK

小部件

自定义小部件的一大变化是引入了 GtkLayoutManager,这是一个新的委托对象,负责大小分配。布局管理器可以选择使用布局子项来保存布局属性。这取代了 GTK 容器(如 GtkBoxGtkGrid)中与布局相关的子属性。

提供了许多布局管理器

  • GtkBinLayout,用于简单的单子容器
  • GtkBoxLayout,用于线性排列的子项
  • GtkGridLayout,用于排列在网格中的子项
  • GtkFixedLayout,用于自由定位和转换的子项
  • GtkCustomLayout,作为将传统的 measuresize_allocate vfuncs 转换为布局管理器的快速方法

未来会出现更多的布局管理器实现。最重要的是,正在进行基于约束的布局管理器的工作。

GtkAssistantGtkStackGtkNotebook 具有公开的
其子项的可访问页面对象。页面对象
也通过列表模型公开。这些容器的非布局相关子属性已转换为这些页面对象上的常规属性。

由于所有现有的子属性都已转换为常规属性、移动到布局属性或移动到此类页面对象,因此已从 GtkContainer 中删除了对子属性的支持。

核心的 GtkEntry 功能已移至新的 GtkText 小部件中,该小部件还实现了扩展的 GtkEditable 接口。GTK 中所有现有的条目子类都已转换为包装 GtkText 小部件的 GtkEditable 实现。这还包括一个新的 GtkPasswordEntry

其他更改

GTK 小部件可以使用投影线性变换来转换其子项。
此功能在 CSS 中可用,并且
作为 gtk_widget_allocateGskTransform 参数。GtkFixed
第一个公开此功能的容器。有关更多示例,
请参阅 GtkRevealer 的摆动过渡、旋转过渡
GtkStack 或 gtk4-demo 中的固定布局示例。

已引入了许多列表模型,用于内部使用
并作为公共 API:GtkMapListModelGtkSliceListModelGtkSortListModelGtkSelectionModelGtkSingleSelection。当我们引入基于列表模型的 GtkListView 时,它们将得到更广泛的应用。

GtkBuilder 可以内联指定对象值属性,而不是通过 ID 引用它们,gtk4-builder-tool 的 simplify 命令已获得一个选项,可自动将 GTK 3 UI 定义文件转换为 GTK 4。

即将推出

有关 GTK 4 仍将推出的内容的更多信息,请在 Discourse、IRC 上找到我们,或在此处查看 这里

GTK 4 中的布局管理器

自 GTK 最初设计以来,容器和布局策略一直是其设计的主要组成部分。如果您希望您的小部件根据特定的策略布局其子项,则必须实现 GtkContainer 以处理子小部件的添加、删除和迭代,然后必须实现 GtkWidget 中的大小协商虚拟函数来测量、定位和调整每个子项的大小。

GTK 4 开发周期的一个主要主题是将更多功能委托给辅助对象,而不是将其编码到 GTK 提供的基类中。例如,我们将事件处理从 GtkWidget 描述的信号处理程序移至事件控制器,并将渲染委托给 GtkSnapshot 对象。该方向的另一个步骤是将布局机制从 GtkWidget 本身分离到辅助类型 GtkLayoutManager

布局管理器

布局管理器是负责测量和调整小部件及其子项大小的对象。每个 GtkWidget 都拥有一个 GtkLayoutManager,并使用它代替 measure()allocate() 虚拟函数 - 这些函数即将消失。更改的要点:无需子类化 GtkWidget 来实现其布局策略,您可以子类化 GtkLayoutManager,然后将布局管理器分配给小部件。

就像在旧的 GtkWidget 代码中一样,您需要覆盖一个虚拟函数来测量布局,称为 measure(),它取代了 GTK 3 的 get_preferred_* 系列虚拟函数

static void
layout_measure (GtkLayoutManager *layout_manager,
                GtkWidget        *widget,
                GtkOrientation    orientation,
                int               for_size,
                int              *minimum,
                int              *natural,
                int              *minimum_baseline,
                int              *natural_baseline)

测量后,您需要将大小分配给布局;这发生在 allocate() 虚拟函数中,它取代了之前 GTK 主要版本中受人尊敬的 size_allocate() 虚拟函数

static void
layout_allocate (GtkLayoutManager *layout_manager,
                 GtkWidget        *widget,
                 int               width,
                 int               height,
                 int               baseline)

在更深奥的一方面,您还可以覆盖 get_request_mode() 虚拟函数,该函数允许您声明布局管理器是请求恒定大小,还是其大小之一取决于相反的大小,例如高宽比或宽高比

static GtkSizeRequestMode
layout_get_request_mode (GtkLayoutManager *layout_manager,
                         GtkWidget        *widget)

您可能会注意到,每个虚拟函数都会传递布局管理器实例以及正在使用该布局管理器的小部件。

当然,这对 GTK 小部件的各种工作方式产生了更大的影响,最明显的是,布局代码的所有复杂性现在可以保留在其自己的对象中,通常是不可导出的,而小部件可以保持可导出并变得更简单。

此工作的另一个特点是,如果您想更改容器的布局策略,您可以在运行时更改布局管理器;您还可以拥有每个小部件的布局策略,而无需向小部件代码添加更多复杂性。

最后,布局管理器允许我们摆脱 GTK 的特殊情况之一,即:容器子属性。

子属性

GtkContainer 的内部深处,本质上是 GObject 属性相关代码的副本,其唯一的工作是为派生自 GtkContainer 的类型实现“子”属性。这些容器/子属性仅在子项作为特定类别的容器的父项时存在,并且出于各种原因使用 - 但通常用于控制布局选项,例如盒子和类似盒子的容器中的打包方向;GtkFixed 内部的固定位置;或笔记本选项卡小部件的展开/填充规则。

子属性很难使用,因为它们需要特殊的 API 而不是通常的 GObject API,因此需要在 GtkBuilder、gtk-doc 和语言绑定中进行特殊情况处理。子属性也附加到容器的实际直接子项,因此如果小部件插入子项 - 例如,GtkScrolledWindowGtkListBox 所做的那样 - 那么您需要保留对子项的引用,以便更改适用于您自己的小部件的布局。

在 GTK 的主分支中,我们摆脱了其中的大部分 — 要么简单地在存在实现相同功能的实际小部件 API 时删除它们,要么通过创建辅助 GObject 类型并将子属性移动到这些类型。最终目标是在 GTK 4 推出之前删除所有这些属性以及 GtkContainer 的相关 API。对于与布局相关的属性,GtkLayoutManager 提供了自己的 API,以便在将子项添加到使用布局管理器的小部件或从使用布局管理器的小部件中删除子项后,自动创建和销毁对象。创建的对象是可内省的,并且在文档或绑定方面不需要特殊情况处理。

您从派生您自己的 GtkLayoutChild 类类型开始,并像对任何其他 GObject 类型一样添加属性。然后,您覆盖 GtkLayoutManagercreate_layout_child() 虚拟函数

static GtkLayoutChild *
create_layout_child (GtkLayoutManager *manager,
                     GtkWidget *container,
                     GtkWidget *child)
{
  // The simplest implementation
  return g_object_new (your_layout_child_get_type (),
                       "layout-manager", manager,
                       "child-widget", child,
                       "some-property", some_property_initial_state,
                       NULL);
}

之后,只要小部件仍然是使用布局管理器的容器的子项,您就可以访问您的布局子对象;如果子项从其父项中移除,或者容器更改了布局管理器,则布局子项会自动被回收。

新的布局管理器

当然,仅仅在 GTK 中拥有 GtkLayoutManager 类对我们没有任何好处。GTK 4 为应用程序和窗口小部件开发人员引入了各种布局管理器。

  • GtkBinLayout 实现了 GtkBin 的布局策略,并增加了一个特性,它支持多个子项堆叠在一起,类似于 GtkOverlay 的工作方式。您可以使用每个小部件的对齐和扩展属性来控制它们在分配区域内的位置,而 GtkBinLayout 始终会要求尽可能多的空间来分配其最大的子项。
  • GtkBoxLayoutGtkBox 实现的布局策略的直接移植;GtkBox 本身已被移植为在内部使用 GtkBoxLayout
  • GtkFixedLayoutGtkFixedGtkLayout 的固定布局定位策略的移植,并增加了允许您定义通用变换的功能,而不是每个子项的纯 2D 平移;GtkFixed 已被修改为使用 GtkFixedLayout 并使用 2D 平移——而 GtkLayout 已被合并到 GtkFixed 中,因为它唯一显著的特性是 GtkScrollable 接口的实现。
  • GtkCustomLayout 是一个方便的布局管理器,它接受过去用于 GtkWidget 虚函数覆盖的函数,它主要用于在将现有小部件移植到未来的布局管理器时作为桥梁。

我们仍在实施 GtkGridLayout 并使 GtkGrid 在内部使用它,遵循与 GtkBoxLayoutGtkBox 相同的模式。GTK 中的其他小部件也将在此过程中获得自己的布局管理器,但在此期间,它们可以使用 GtkCustomLayout

最后一步是实现基于约束的布局管理器,这将使我们能够创建复杂的、响应式的用户界面,而无需将小部件打包到嵌套的层次结构中。基于约束的布局值得单独写一篇博客文章,敬请关注!

GTK 4 中的条目

最近在 GTK 主分支中进行的一项较大的重构是重新构建条目层次结构。这篇文章总结了发生了什么变化,以及我们为什么认为这种方式更好。

GTK 3 中的条目

让我们先来看看 GTK 3 中的情况。

GtkEntry 是这里的基础类。它实现了 GtkEditable 接口。GtkSpinButton 是 GtkEntry 的子类。多年来,添加了更多的东西。GtkEntry 获得了对条目完成、嵌入图标和显示进度的支持。我们还添加了另一个子类,GtkSearchEntry。

这种方法的一些问题立即显现出来。gtkentry.c 超过 11100 行代码。不仅很难向这个大型代码库添加更多功能,而且也很难对其进行子类化——这是创建您自己的条目的唯一方法,因为所有单行文本编辑功能都在 GtkEntry 内部。

GtkEditable 接口非常旧——它在 GTK 2 之前就存在了。不幸的是,它作为一个接口并没有真正成功——GtkEntry 是唯一的实现,并且它以令人困惑的方式在内部使用接口函数。

GTK 4 中的条目

现在让我们看看 GTK 主分支中的情况。

我们做的第一件事是将 GtkEntry 的核心文本编辑功能移到一个名为 GtkText 的新小部件中。这基本上是一个没有所有额外功能(如图标、完成和进度)的条目。

通过向 GtkEditable 接口添加一些更常用的功能(如 width-chars 和 max-width-chars),并使 GtkText 实现它,我们使 GtkEditable 接口更加有用。我们还添加了帮助程序 API,使将 GtkEditable 实现委托给另一个对象变得容易。

现在,“复杂”的条目小部件(GtkEntry、GtkSpinButton、GtkSearchEntry)都是复合小部件,它们包含一个 GtkText 子项,并将其 GtkEditable 实现委托给这个子项。

最后,我们添加了一个新的 GtkPasswordEntry 小部件,它接管了 GtkEntry 过去拥有的相应功能,例如显示大写锁定警告

或让用户查看内容。

为什么这样更好?

此重构的主要目标之一是使在 GTK 外部创建自定义条目小部件更容易。

过去,这需要对 GtkEntry 进行子类化,并导航一个复杂的 vfuncs 迷宫进行覆盖。现在,您只需添加一个 GtkText 小部件,将您的 GtkEditable 实现委托给它,就可以毫不费力地拥有一个功能齐全的条目小部件。

您可以在 GtkText 组件周围添加花哨的东西,并且具有很大的灵活性。例如,我们在 gtk4-demo 中添加了一个标签条目,现在可以在 GTK 外部轻松实现。

从 GTK 3 移植时,这会影响您吗?

在将代码移植到这种新的条目处理方式时,需要记住一些可能的陷阱。

GtkSearchEntry 和 GtkSpinButton 不再派生自 GtkEntry。如果您看到有关从这些类之一强制转换为 GtkEntry 的运行时警告,您很可能需要切换到使用 GtkEditable API。

GtkEntry 和其他复杂的条目小部件不再是可聚焦的——焦点会转移到包含的 GtkText。但是 gtk_widget_grab_focus() 仍然有效,并将焦点移动到正确的位置。您不太可能受到此影响。

GtkEntry 中已删除大写锁定警告功能。如果您使用 visibility==FALSE 的 GtkEntry 来表示密码,则应切换到 GtkPasswordEntry。

如果您使用 GtkEntry 进行基本编辑功能,并且不需要任何额外的条目功能,则应考虑使用 GtkText。

测试 GTK 的 Discourse

在过去的 20 年左右的时间里,GTK 使用 IRC 和邮件列表来讨论与该项目相关的问题。多年来,电子邮件的使用率有所下降,维护基础设施的开销有所增加;在服务提供商看来,向数百或数千人发送电子邮件越来越难以与垃圾邮件区分开来,而 GNOME 不得不尝试请求例外——这并不容易获得,而且很容易被撤销。最重要的是,用于管理邮件列表的基础设施相当陈旧且脆弱,并且不必要地分为多个子类别,这使得跟踪讨论比必要的更困难。

在 GTK 团队、GNOME 基础设施维护人员以及 GTK 社区的广泛讨论之后,我们决定开始试运行 Discourse 作为邮件列表的替代方案,首先,也是为 GTK 社区提供一个官方场所来讨论 GTK 的开发和与 GTK 的互动——以及其余的核心 GNOME 平台:GLib、Pango、GdkPixbuf 等。

您可以在 discourse.gnome.org 上找到 Discourse 实例。在其中,您可以使用 平台核心类别来讨论有关核心 GNOME 平台的问题;您可以使用适合您主题的标签,并订阅您感兴趣的标签。

我们还计划将 Wiki 上的某些页面也迁移到 Discourse,特别是我们希望从社区获得反馈的页面。

我们仍在 研究如何迁移与 GTK 相关的各种邮件列表的用户,以便关闭列表并拥有一个单一场所,而不是分割社区;与此同时,如果您订阅了一个或多个此类列表

  • gtk-devel-list
  • gtk-app-devel-list
  • gtk-list
  • gtk-i18n-list

那么您可能需要查看 Discourse,并加入那里的讨论。

布鲁塞尔 GTK 黑客马拉松的报告

感谢 GNOME 基金会,各种 GTK 开发人员能够在 FOSDEM 之后在布鲁塞尔会面,参加我们的 年度黑客马拉松之一。

黑客马拉松的主要主题是

  • 回顾过去 6-12 个月内已合并到主分支的工作,以便每个人都在同一页面上
  • 讨论仍在单独分支中进行的功能,评估它们的完成状态,并确定障碍
  • 找出 GTK 4.0 的首次发布的障碍是什么

与在线交流渠道相比,黑客马拉松使我们能够以更大的带宽进行此类讨论,因此它们对于项目来说非常重要。

您可以在 wiki 上查看完整的议程,我们将确保撰写有关其中最重要事项的文章。

讨论的最大事项是引入新的列表模型和列表/网格视图小部件;统一的按键处理 API;将布局管理策略与容器解耦,并引入约束布局管理;合并来自 libhandy 的小部件的可能性,以允许编写对窗体因素变化做出响应的应用程序;切换到纯声明式菜单描述 API,并删除公共菜单小部件;向 GtkWidget 添加 2D 和 3D 变换;实现应用程序可以使用的动画 API。

  • 列表模型和列表/网格小部件 — 我们真的希望弃用 GtkTreeViewGtkIconView,但是现有的替代品 GtkListBoxGtkFlowBox 在扩展到非常庞大且动态的数据集时性能不够。我们需要更好的数据存储类型,可以组合这些类型来执行映射、过滤和排序等操作,但也可以避免在调整大小和绘制小部件时遍历所有元素。Benjamin Otte 已经向 GTK 添加了各种模型,并且正在开发可以有效显示其内容的列表和网格视图小部件。Benjamin 和其他 GNOME 应用程序开发人员正在为专门收集更多需求并获得有关新 API 反馈的单独黑客马拉松确定各种利益相关者。
  • 统一的按键处理 API — 现在我们已将所有指针和触摸输入处理从事件转移到手势,我们希望对按键处理也做同样的事情,例如按键绑定、助记符和快捷键。总体设计基于触发动作,并允许对 GTK 检查器当前可用的所有“快捷方式”进行内省,以便于调试。已经有一个开发分支可用。
  • 布局管理器 — 在 GTK 3 中,布局是由容器对其子项强制执行的;我们希望能够将布局与小部件解耦,并将其移动到单独的委托对象层次结构中。布局管理器使我们能够降低编写新小部件的复杂性;它们将布局代码保留在单独的、不可导出的类型中;它们使我们能够简化工具包内部结构,以至于我们将来甚至可以将 GtkWidget 作为可实例化的类型。布局管理器是向 GTK 添加基于约束的布局管理的第一步,该管理可以避免嵌套框来创建复杂的 UI。已经有一个开发分支可用。有关约束布局的更多信息,您可以查看 GTK 3 的Emeus 实验库
  • 合并 libhandy 中的小部件 — Adrien Plazas 概述libhandy 目前提供的内容,以及将来直接从 GTK4 中获得哪些内容会很有用。我们讨论了反应式布局以及用百分比表示大小的能力,以及可能使用约束来获得类似结果的可能性。
  • 声明式菜单 — 多年来,GTK 对不同的菜单 API 进行了迭代;从用小部件构建菜单,到 GtkUIManager,到 GtkBuilder,再到 GMenu;我们还转向声明弹出菜单的行为,以便让窗口系统更准确地显示它们,而不会暴露全局坐标。有很多重叠,但没有明确的赢家,主要是因为我们仍然允许使用小部件来构建应用程序菜单和上下文菜单。完全切换到声明式风格的菜单,添加新的 API 使它们更具表现力,并将 GtkMenu 和朋友作为工具包的私有实现,将使我们能够获得诸如能够检查所有菜单(即使在进程外)、插件系统可操作的菜单(无需创建小部件并跟踪它们)、避免定位错误之类的事情。wiki 上提供了 完整的初步提案,Matthias Clasen 正在 一个开发分支中将上下文菜单切换到 GMenu
  • 小部件转换 — 遗憾的是,Timm Bädert 无法参加黑客马拉松,但我们一直在审查他为 GTK 小部件添加 2D 和 3D 变换的 开发分支,我们对此感到非常兴奋。
  • 动画 — 我们希望为 GTK4 实现的最后一件事是 GTK 小部件的动画框架,以替换当前通用的“帧刻度回调”。它的模型是 Clutter 显式动画 API,该 API 又基于 Core Animation 和 CSS3 过渡。这项工作仍处于设计阶段,但您可以预期很快就会有相关的开发分支落地。

除了这些大主题,我们还讨论了各种较小的主题

  • 提高性能和内存使用;我们希望在帧时钟阶段公开 SysProf 计数器,以便我们可以轻松识别问题。
  • 改进测试套件,尤其是在报告失败方面;目前,我们必须浏览 CI 失败日志,但我们希望使用 GitLab CI 基础结构发布适当的报告
  • 将子属性替换为辅助对象上的真实 GObject 属性,尤其是对于布局管理器;这将使文档、内省和用法更加清晰。
  • 完成拖放重做,以获得更现代的 API。
  • 为“窗口式”对象(例如窗口、对话框、弹出窗口、菜单/弹出窗口)添加顶级接口,这对于建立通用行为并消除 GtkWindow 中的黑客行为和复杂性非常有用。

最后,是的:我们确实从 GTK 中删除了“加号”。 ;-)

主题更改,重新审视

快速更新上周关于主题更改的帖子

我们已经发布了 3.24.4 版本,以修复 3.24.3 中的一些疏忽。此版本包含新的主题,我们将将其推送到下一个版本。

我们还制作了另一个 NewAdwaita tarball,其中包含自上周以来收到的一些建议的改进。

尝试一下,并告诉我们您的想法!

GTK 3 中的主题更改

Adwaita 作为默认的 GTK+ 主题已经有相当一段时间了(在所有平台上)。它为我们服务得很好,但 Adwaita 一段时间没有进行重大更新,并且人们希望对其进行刷新。

更新 Adwaita 是一项挑战,因为大多数 GTK 应用程序都使用稳定的 3.x 系列,并且其中一些应用程序为其自己的自定义小部件包括与 Adwaita 兼容的主题。鉴于此发布系列的稳定性,我们不希望为应用程序造成主题兼容性问题。同时,3.x 是当今使用的主要 GTK 版本,我们希望确保 GTK 应用程序不会感到过时或老式。

试验

已经考虑和讨论了许多解决此问题的方法。其中,一项尝试性的计划已被提出,以试验一组有限的主题更改,并有可能将其纳入未来的 GTK 3 版本中。

我们希望,由于主题更改的范围有限,它们不应给应用程序带来问题。但是,我们不想仅仅寄希望于希望。因此,接下来的三周被指定为测试和咨询期,如果一切顺利,我们希望将该主题合并到 GTK 3.24.4 版本中。

应该强调的是,这些更改仅限于 Adwaita 本身。自 GTK 3.22 以来,GTK 的 CSS 选择器和类没有更改,Adwaita 中的更改不会影响其他 GTK 主题。

Adwaita 更新的主题与 GTK 3.24.3 版本并行提供,作为一个单独的 tarball,可以从此处下载。邀请 GTK 应用程序开发人员尝试 3.24.3 以及新版本的 Adwaita,并报告他们遇到的任何问题。GTK 团队和 Adwaita 作者也将进行自己的测试。有关如何以各种方式测试新主题的详细信息,请参见此处

我们希望在 GTK 的稳定性承诺和提供最新应用程序的愿望之间取得平衡。这是一个难以把握的平衡,我们渴望在此过程中与 GTK 用户互动!

主题更改

本文的其余部分总结了对主题所做的更改。这有望证明这些更改的范围有限。它还将帮助开发人员了解测试时应注意的事项。

颜色

许多 Adwaita 颜色都进行了非常轻微的调整。新颜色比以前的版本更鲜艳,因此使 Adwaita 更具活力。新颜色也是更广泛的调色板的一部分,该调色板正在用于应用程序图标。这些颜色也可以用于自定义应用程序样式。

颜色变化很微妙,因此新旧版本之间的任何兼容性问题都不应很严重。蓝色仍然是蓝色(只是稍微不同的阴影!)红色仍然是红色。从视觉上看,主题的深色和浅色版本在很大程度上保持不变。

Adwaita 的深色变体,显示了旧(左)和新(右)之间颜色上的细微变化。

请注意,在深色主题中,按钮的红色略微减弱。

标题栏和按钮

在更新的 Adwaita 版本中,大多数小部件没有被特别更改。但是,有两个地方的小部件进行了特定更改,即标题栏和按钮。在这两种情况下,都努力使其更轻巧、更优雅。

按钮的实线边框已被阴影取代。它们的背景也更加平坦,并且它们的角更加圆润。它们的形状也略有改变。

标题栏已更新以补充按钮的更改。这主要是通过加深它们的背景来实现的,以便为按钮提供足够的对比度。标题栏的焦点和非焦点状态之间的对比度也增加了。这使得用户更容易识别焦点窗口。

乍一看,这些变化是最显著的,但它们是通过一些非常小的代码更改实现的。

GNOME 日历应用程序中的标题栏(旧版本在顶部,新版本在底部)

开关

除了标题栏和按钮外,唯一被更改的小部件是开关。当 GTK 首次引入开关时,它们在桌面上是一个相当新的概念。因此,它们包含了明确的“开”和“关”标签,以传达开关如何操作。自那时以来,开关小部件已变得无处不在,用户已经熟悉了不包含标签的开关。

最新的 Adwaita 更改使主题与其他平台保持一致,并通过删除标签并引入更圆润的形状,使开关更紧凑和现代。

其他地方,没有变化

除了上述更改外,Adwaita 中的其他变化很少。绝大多数小部件保持不变,尽管颜色略有变化。一般来说,UI 布局不应更改,用户应该对这些更改感到舒适。

找出差异(旧版本的 Adwaita 在左侧,新版本在右侧)

结论

请尝试新主题。我们希望您喜欢它!

我们感谢您的反馈——特别是如果您是 GTK 应用程序开发人员。您可以在 IRC(GimpNet 上的 #gtk+ 频道)或通过 gtk-devel-list 邮件列表提供反馈,或者在 gitlab 中提交问题。

Guadec GTK+ BoF 的报告

GTK+ 团队在 Guadec 的 BoF 日子里进行了一整天的规划会议,我们有一个满屋子的参会者,包括来自几个下游的代表,不仅仅是 GNOME。

我们也有一个非常密集的 议程

GTK+ 3

我们首先回顾了我们之前 概述的 GTK+ 3 计划。

除了那里提到的内容外,我们还计划反向移植新的事件控制器,以使移植到 GTK+ 4 更容易。我们还将添加 meson 构建支持,以帮助 Windows 构建。

3.24 版本将有效地延续 3.22 分支,并且应该可以完全安全地作为稳定更新发布在发行版中。

我们计划在 GNOME 3.30 发布时发布 GTK+ 3.24.0。

GTK+ 4 遗留问题

当天的大部分时间都用于讨论 GTK+ 4。我们回顾了路线图上剩余的任务列表

  • 完成 DND:GTK+ 级别的姿势,本地快捷方式
  • 引入 GtkToplevel 并干净地支持弹出窗口
  • 添加转换
  • 创建快捷方式事件控制器以替换按键绑定
  • 将 GtkTextView 移植到渲染节点
  • 分析 cairo 后端,确保其性能与 GTK+ 3 相当
  • 移植各种依赖库
    • vte
    • webkit
    • libchamplain
    • gtk-vnc
    • gtk-spice

这些任务中的大多数都有相应的名字,但如果您想帮助完成这些任务中的任何一个,请务必联系我们!

此列表中明显缺少以前在路线图上的一些内容

  • 基于约束的布局 (emeus)
  • 着色器编译器和应用程序提供的着色器
  • 设计器支持

如果出现合并请求,所有这些仍然可以发生,但我们认为我们不应该阻止它们。它们可以在 GTK+ 4 外部开发,并成为 GTK+ 5 的素材。

GTK+ 后端

我们花了一些时间评估 GTK+ master 中 GDK 后端的状态。

Windows 后端状态良好。我们有几个人帮助维护和功能开发,meson 使构建它更容易,并且我们有它的 ci。

Quartz 后端的状态要差得多。它没有保持在可构建状态,没有人为其提供修复或功能开发,并且我们没有 ci。我们提供了一台可用于 ci 的 macbook,并且建议我们可以使用 travis ci 来进行 OS X。

GTK+ 时间线

我们在这方面花费了很长时间,但没有达成 100% 的共识,但如果我们继续在剩余的遗留问题上取得良好进展,那么在 2019 年春季发布 GTK+ 4 似乎是现实的。

当我们发布 GTK+ 3.96 时,我们还将宣布 GTK+ 4.0 的日期。我们希望能够在 GNOME 3.32 之前承诺发布,以便 GNOME 应用程序开发人员可以将他们的 master 分支切换到 GTK+ 4,而无需担心这会中断 3.32 的其他开发。

应用程序移植

我们现在非常希望从应用程序端口获得反馈。但是我们处于一个有点困难的境地,因为在完成 GtkToplevel 和快捷方式控制器工作之前,我们不能合理地声称完成了主要的 API 工作。

我们此时对应用程序作者的建议是

  • 如果您有点冒险精神,请在分支上移植到 3.94。在 GTK+ 4 开发的剩余时间内,应该可以保持其正常工作而无需太多工作。
  • 如果您没有那么冒险,请等到 3.24 发布,使用它来准备您的端口,然后移植到 GTK+ 3.96。
  • 无论哪种方式,请将您的端口提供给用户进行测试,无论是作为常规版本还是作为带有捆绑 GTK+ 的 Flatpak。

GLib 分歧

下午,我们花了一些时间讨论 GLib。我们回顾了一系列大大小小的项目。值得注意的亮点:GProperty 可能会在 2.60 版本中出现,并且我们可能很快就可以使用 g_autoptr。

其他想法

我们讨论了许多其他我们可以而且应该做的事情。

例如,有人建议(并普遍同意)我们应该将 gsk 合并到 gdk 中,因为它很小,并且内部结构有些交织。还建议在 gtk/ 中创建子目录,例如用于 css 机制。

GLib 2.58 的新闻

明年 9 月,GLib 将达到 2.58 版本。在过去的两个开发周期中发生了一些变化,最值得注意的是 Meson 构建的改进,这反过来又提高了 GLib 对 Windows、macOS 和 Android 等平台的移植性。现在是时候评估 GLib 的当前状态,并强调一些将影响基于 GLib 的代码的更改了。

  • Meson – 感谢 Nirbheek Chauhan 和 Xavier Claessens 的持续工作,Meson 构建一直在不断改进,以至于我们可以开始将其切换为默认构建系统。该计划——正如 邮件列表中概述的——是使用 Meson 发布 GLib 2.58,同时将 Autotools 构建保留在树中并在发布存档中可用;然后,我们将在下一个开发周期中删除 Autotools 构建,并发布没有 Autotools 支持的 GLib 2.60。我们非常欢迎 Linux 发行版开始在他们的构建器中测试 Meson 构建;我们已经将 Meson 构建作为我们的CI流程运行了一段时间,但更多的曝光将带来我们遗漏的最终回归;此外,如果使用不同于 GCC/Clang/MSVC 的工具链的人员开始尝试 Meson 构建并报告错误,那就太好了。与此同时,如果您在 macOS 和 Windows 上使用 GLib,我们已经建议您切换到 Meson 来构建 GLib,因为它比 Autotools 更容易且更好地与这些平台集成
  • 可靠性和可移植性 – GLib 与 GNOME 的其余部分一起切换到 GitLab,这意味着能够在 GNOME Continuous 构建之外运行持续集成。现在我们运行CI在多个工具链、多个构建系统和每个提交和合并请求的多个平台上进行测试,这大大降低了构建失败的可能性。我们还提高了测试套件中的代码覆盖率。当然,我们总是可以做得更好;例如,我们没有一个CImacOS 和 Solaris 系列操作系统的运行器,并且如果能有更多 *BSD 系列的运行器,我们将非常感激。我们已经发布了求助信息,如果您有多余的机器和一些带宽可以捐赠
  • *BSD 上的文件监控 – 关于 *BSD 系列,Martin Pieuchot 和 Ting-Wei Lan 对 GIO 中用于文件监控的 kqueue 后端进行了彻底改造;新代码更简单、更健壮,并通过了所有测试
  • 使用 posix_spawn() 实现高效的进程启动 — 感谢 Daniel Drake,如果平台的 C 库支持,GLib 现在可以在特定情况下使用 posix_spawn();与手动调用 fork() + exec() 相比,这允许在内核中命中快速路径;这些快速路径在内存受限的平台上运行时尤其有益
  • 引用计数类型和分配 — GLib 在其许多类型中使用引用计数作为内存管理和垃圾回收机制,但缺乏公共 API 来允许其他人在其自己的数据结构中实现相同的语义;这导致了大量的复制粘贴和重新实现,并且通常会导致诸如饱和和线程安全方面未定义的行为。GLib 2.58 具有 grefcountgatomicrefcount 类型,以及它们的 API,以减少这种重复。此外,借鉴了 Rust 等其他语言的经验,GLib 提供了一种在内存分配上添加引用计数语义的方法,通过添加一个低级 API,允许您分配没有引用计数字段的结构,并自动向它们添加引用计数语义
  • 弃用 – 在上一个开发周期中,一些软弃用已成为真正的弃用
      • g_type_class_add_private() 在我们引入实例私有数据宏五年后终于被弃用;如果您仍然在类初始化中使用该函数,请切换到 G_DEFINE_TYPE_WITH_PRIVATEG_ADD_PRIVATE
      • g_main_context_wait() 已正式弃用,但您应该已经看到了关于其使用的运行时警告
      • GLib 提供的 GTest 测试工具 gtester 已弃用;如果您使用的是 Autotools,则应使用TAPAutomake 附带的测试工具

在过去的这个周期中,GLib 中有很多贡献,这要归功于 Philip Withnall 不懈的努力;他在审查补丁、分类错误以及实施项目开发过程中的更改方面发挥了重要作用。切换到 GitLab 也改进了贡献流程,有更多开发人员打开了合并请求

  • 2.54.0..c182cd68:来自 143 位开发人员的 968 个变更集,高于 2.53 开发周期中的 412 个变更集和 68 位开发人员
  • 总共添加了 31851 行代码,删除了 27976 行代码(差值:+3875
变更集最多的开发人员
Philip Withnall 303 31.3%
Xavier Claessens 79 8.2%
Emmanuele Bassi 69 7.1%
Christoph Reiter 42 4.3%
Ting-Wei Lan 21 2.2%
Chun-wei Fan 21 2.2%
Nirbheek Chauhan 21 2.2%
Ondrej Holy 20 2.1%
Руслан Ижбулатов 20 2.1%
Mikhail Zabaluev 20 2.1%
Simon McVittie 15 1.5%
Matthias Clasen 14 1.4%
Christian Hergert 13 1.3%
Iñigo Martínez 12 1.2%
Bastien Nocera 10 1.0%
Rafal Luzynski 9 0.9%
Michael Catanzaro 9 0.9%
Will Thompson 8 0.8%
Allison Lortie 8 0.8%
Daniel Boles 8 0.8%

请务必使用 GLib 2.57.2 测试您的代码,这是迈向 2.58.0 稳定版本的下一个开发快照。

GTK+ 3.94

今天,我们发布了 GTK+ 3.94.0。同样,自上次发布以来已经有一段时间了,因此有必要总结一下此版本中的新功能。这里真的有很多内容要介绍,因此本文仅重点介绍最重要的更改。

此版本是我们迈向 GTK+ 4 的另一个里程碑。虽然仍然有一些未完成的事项,但此版本更接近我们希望使用 GTK+ 4 实现的目标。

GSK

Broadway 后端现在有一个 GskRenderer,因此 Broadway 的未来看起来要好得多。

我们引入了一种新的渲染节点类型 GskOffsetNode,它是一个简化的 GskTransformNode,并且在我们沿着渲染节点树上下移动时接管了转换内容的工作。通过此更改,我们现在能够缓存多个帧的窗口小部件的渲染节点,并在必要时重新定位它们。

我们还引入了 GskDebugNodes,它接管了节点名称,并使我们能够简化一些用于创建渲染节点的 GTK+ API。

在回退到使用 Cairo 进行渲染时,我们现在使用录制表面而不是图像表面,因此我们可以在不同的比例下重放渲染。

一个重要的新操作是 gsk_render_node_diff,用于比较两个渲染节点树(有关详细信息,请参见下文)。

GDK

遵循将 GDK API 与 Wayland 而不是 X 对齐的总体趋势,GdkWindow 被重命名为 GdkSurface。

GdkTexture API 得到了改进,具有新的 GdkMemoryTexture 和 GdkGLTexture 子类,并且引入了强大的新抽象 GdkPaintable

GdkPaintable 表示可以在任何尺寸的任何位置绘制的对象,而无需任何类型的布局。这受到了其他地方的类似概念的启发,例如 ClutterContent、HTML/CSS Paint Sources 或 SVG Paint Servers。为了展示这个概念的强大之处,在 gtk4-demo 中添加了一些新演示

DND 代码继续进行重大重构。它现在使用与 3.93 中引入的用于剪贴板处理的相同内容提供程序基础结构,并且它具有用于 DND 操作的源侧和目标侧的单独对象。此处将会有更多更改。

GTK

窗口小部件

GTK+ 获得了对显示视频的支持,带有 GtkVideo 和 GtkMediaControls 窗口小部件,并且还有一个新的 GtkPicture 窗口小部件,用于将图像查看与 GtkImage(实际上是关于图标的)分离。

GtkFontChooser 允许调整 OpenType 功能和字体变体,并且用于颜色 Emoji 输入的 Ctrl-Shift-e 已被可以通过 GtkEntry::enable-emoji-completion 属性启用的补全功能所取代。

输入

GtkWidget 中特定于事件的信号继续消失。此时只剩下 ::event,但它也会消失。相反,我们正在使用事件控制器,并且添加了几个新的控制器来覆盖所有需要的事件

  • GtkEventControllerMotion
  • GtkEventControllerKey
  • GtkGestureStylus

为了使过渡更容易,现在可以在 ui 文件中创建事件控制器。

Wayland 有自己的平台输入法,基于 Wayland 文本协议。

绘图

::draw 信号已删除,所有窗口小部件都必须实现 ::snapshot。它们现在可以创建自己的 GtkSnapshot 实例进行中间渲染。剪切不再应用于 GTK+ 级别 - 如果需要,窗口小部件可以自由地在其分配之外绘制。

窗口小部件失效已更改,它现在通过丢弃失效窗口小部件的缓存渲染节点,并重新创建渲染节点树的缺失部分来工作。

为了查找需要重绘的区域,GTK+ 会对上一帧和当前帧的渲染节点树进行差异比较,并应用一些启发式方法来防止矩形数量增长过大。

GTK+ 检查器可让您跟踪失效,您可以在此处看到其运行情况

其他更改

GTK+ 不再支持通用可加载模块。输入法、打印后端和媒体后端已转换为 GIOModules 和扩展点。

平台 im 模块(即 Windows、Wayland、Broadway im 上下文)始终包含在内,并且在其平台上默认启用。

GDK 中的 Vulkan 支持现在可以使用 GDK_VULKAN_DEVICE 环境变量指定的特定设备。使用 GDK_VULKAN_DEVICE=list 查看所有可用设备。

试一试

使用 GTK+ 3.94.0,应该可以开始移植应用程序。 文档有一个初始移植指南。