如何在Windows 7+和MSYS2上获得GTK3的本地窗口装饰

17

我正在尝试将我的应用程序从Linux移植到Windows,但在主题方面遇到了问题。在Linux中,这很容易实现,只需编译即可使用良好的主题并呈现本地外观。

我已经在MSYS2中安装了gtkmm3和gtk3,并使用CMake构建它。这一步没问题,但我需要将所有dll复制到二进制文件目录才能执行它。我正在尝试创建“解压并执行”软件包。

我的问题是,应用程序外观不协调。它看起来一点也不本地化。窗口周围有阴影,在Windows10中还好,但在Windows 7中看起来不本地化。此外,缺少几个图标。

bad gtk3 application theme on Windows10

即使是gtk3-demo也以同样的方式显示出非本地化(但至少最小化/最大化/关闭图标是正确的)。

因此问题是:如何在Windows上实现GTK3应用程序的本地化外观?或者至少本地化窗口装饰?

谢谢


1
@oldtechaa,GTK+中的win32主题是内置在GTK+中的;C++与此无关。那里缺少图像是由于配置不正确的图标主题,与源代码无关。尽管我想知道为什么“标准”标题栏没有图标,但gtk3-demo使用的GtkHeaderBar却有... - andlabs
2
在msys2 IRC频道上,raymod2说:“他需要将Adwaita主题中的图标复制到二进制文件可以找到的位置。我把我的放在一个名为“share”的文件夹中,与我的应用程序二进制文件放在同一个文件夹中。对于他截图中缺少的图标,他需要将window-close.png、window-maximize-symbolic.symbolic.png和window-minimize-symbolic.symbolic.png放在share/icons/Adwaita/16x16/actions中。”希望这能帮到他。 - David Grayson
谢谢@DavidGrayson,这就是图标的问题所在。 - kracejic
肯定有方法可以做到这一点,因为MyPaint具有适当的本地Windows装饰(不像下面的假XP)。但我找不到他们在代码中实际启用它的任何地方。 - Timmmm
5个回答

16

存在两个子问题:缺失图标和设置正确的主题。

缺失图标

对于缺失的图标,只需要复制这些图标:

  • window-close-symbolic.symbolic.png
  • window-maximize-symbolic.symbolic.png
  • window-minimize-symbolic.symbolic.png

从:C:\msys64\mingw32\share\icons\Adwaita\22x22\actions

到:"您的可执行文件文件夹"\share\icons\Adwaita\22x22\actions

主题

使用Win32本地主题

实际上,GTK3中有一个内置的类似本地的主题。要使用本地主题,只需创建文件 "您的可执行文件文件夹"\etc\gtk-3.0\settings.ini,其中包含以下内容:

[Settings]
gtk-theme-name=win32

win32主题已经集成到GTK3中,只需要使用前一步骤中的三个图标即可。在Windows 7上是这样的:

进入图像描述

问题在于,即使在Windows 10上(包括窗口装饰),这些装饰看起来也是相同的。

根据@andlabs的评论:GTK+ 3使用uxtheme.dll API获取其Windows外观和感觉,不幸的是,Microsoft已经保留了那些类似于Windows 7的窗口边框。(更多内容请参见评论)

您可以在此处查看具有win32主题的Windows 10 Gtk3应用程序:

进入图像描述

使用非默认主题

如果您不满意默认或win32主题,您可以从互联网上使用自定义主题(例如此Flat-Pat)。:) 为了做到这一点,您需要创建配置文件:

"您的可执行文件夹"\etc\gtk-3.0\settings.ini,其中包含以下内容:

[Settings]
gtk-theme-name=Flat-Plat

你需要将主题文件复制到可执行文件所在路径下的目录。

"你的可执行文件夹"\share\themes\Flat-Plat

在该文件夹中,应该存在index.theme文件和gtk-x.x文件夹。 显然,gtk-theme-name和文件夹名称应该匹配。

运行可执行文件后,您应该能够获取不同的主题。

输入图像描述

编辑:Win32 主题是内置的,感谢 @andlabs

编辑2:添加截图

编辑3:添加 Windows 10 截图并纠正事实。


2
等一下,我记得GTK+中仍然有一个win32主题。虽然我不确定3.20版本是否移除了它。如果你将主题字符串设置为win32(如上所示),你的程序会发生什么? - andlabs
窗口装饰不像本地的一样。它们看起来与Windows 7上的相同。我理解,这是因为GTK3主题工作方式的原因 - 我理解它只模仿了本地外观。因此,通过使用win32主题,您可以获得win32外观,该外观旨在适应win7世界,但是Windows 10具有不同的外观,而win32主题无法适应其中。或者我错了吗?有没有办法获得真正的“本地/系统”窗口装饰? - kracejic
2
实际上,我认为GTK+ 3使用uxtheme.dll API来获取其Windows外观和感觉,不幸的是,微软已经将那些窗口边框保持为类似于Windows 7的样式(尝试任何MDI Windows程序即可查看)。您可以检查源代码以确认此事。但我不确定为什么按钮看起来也像Windows 7... - andlabs
2
这看起来不像 Win10 风格。 - Colliot
@Colliot 是的,它确实没有。我没有时间进一步调查这个问题。正如andlab所写的那样,他认为GTK3+使用uxtheme.dll,而Microsoft没有更新它以适应新的W10主题。 - kracejic
显示剩余7条评论

7

您可以设置GTK_CSD=0环境变量,以禁用客户端窗口装饰并启用Windows原生装饰,从而摆脱丑陋的win7样式标题栏和Adwaita样式标题栏。


0
对于像我这样使用(ActiveState)Perl的人来说,/share和/etc需要放置在perl.exe的上一级目录中(例如,如果perl.exe位于C:\Perl64\bin中,则应放置在C:\Perl64中)。

0

实际上,Gtk+3已经与Windows 10兼容,您可以通过将其设置为默认主题来使用本机Windows主题。

gtk-theme-name = MS-Windows

1
它的外观是否现代化(Win10 的窗口装饰)?或者是像 win32 默认主题一样(类似于 Win7 的窗口装饰)?我无法访问 Win10 设备,所以无法测试。 :( - kracejic
这在我的Win10机器上不起作用。你从哪里得到这个信息的? - Jacob
不支持在带有 GTK 3.22 的 Win7 上运行,只支持 GTK-2.0。来源:https://mail.gnome.org/archives/gtk-app-devel-list/2010-September/msg00026.html - user2740652

0

虽然在窗口框架图标方面,GTK_CSD=0表现良好,但似乎默认的拖放(DND)图标也缺失了。

拖动GtkEntry或GtkTreeView内容时会显示拖动图标。

我已经在Gtk+-3.24.4下准备了一个按钮作为拖动源。当拖动按钮时,鼠标光标消失,没有显示拖动图标。

使用gtk_drag_source_set_icon_pixbuf(bt, pixbuf)时,pixbuf会显示为拖动图标。但这只是解决了一半的问题,因为图标上缺少移动/复制指示器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接