如何在 Ubuntu 18.04 中的多个显示器的顶部栏中显示自定义格式的时钟?

Ski*_*ore 10 clock time multiple-monitors top-bar gnome-shell

我有一个非常具体的问题,我没有运气试图找到一个可行的解决方案。我有一台运行 Ubuntu 18.04 的笔记本电脑,使用 2 个外部显示器对接,产生 3 个屏幕。我希望在所有 3 个屏幕上都有我的顶部栏,以便在当前屏幕上轻松查找以查看时间。我使用Multi Monitors Add-On Gnome 扩展来启用它。我用英语运行 Ubuntu,但设置为瑞典语格式。这导致顶部栏中的日期格式非常丑陋且不正确。

顶部酒吧时钟的图像

这几乎是英文格式,带有瑞典语名称的日期和月份。附带说明一下,此本地化“错误”已得到修复,并已为即将发布的 gnome 版本做好准备。

我的主要问题是我想将显示的日期格式更改为:

所需格式的图像

我可以使用许多时钟格式 Gnome 扩展(时钟覆盖日期时间格式)中的任何一个轻松获得这种格式。但是,这些扩展都不适用于我的 Multi Monitors Add-On,​​这让我在主显示器上有一个格式很好的时钟,但在其他两个屏幕上有一个丑陋的格式时钟。我曾尝试让这些插件开发人员进行协作,但显然 gnome 扩展之间的依赖关系是“地狱”。

我也尝试过直接编辑语言环境文件,包括 en_US 和 sv_SE。特别是LC_TIME d_t_fmt日期和时间字符串的格式,但这似乎对时钟格式没有影响。

在最后一次尝试中,我还解压缩了libgnome-shell.so位于 中的文件,/usr/lib/gnome-shell/以尝试使用此答案编辑用于显示时钟的 JavaScript 文件。我查看了dateMenu.js并将calendar.js我能找到的大部分格式字符串更改为我想要的格式%Y-%m-%d。然后我跑了GNOME_SHELL_JS=$HOME/gnome-shell-js gnome-shell --replace,但它似乎再次没有效果。公平地说,我在这里的水域很深,我的尝试肯定会失败。因此,解决方案可能仍然在这种方法中。

有没有人有过这样的情况的经验?使用 Ubuntu 18.04 更改多台显示器上显示的日期和时间格式?随意尝试我已经尝试过的东西,因为我当然会错过一些可以使它工作的东西。

Ste*_*eve 13

BLUF:这是一种永久且干净的方式,无需使用扩展即可根据自己的喜好更改 Gnome 顶部条形时钟的格式。

我还想在 Gnome 顶部栏中为时钟显示一个自定义格式的字符串,但只有一个显示。但是,此答案也将扩展到您的问题,并允许您仅使用多显示器顶部栏扩展。在我的情况下,我的目标是简单地执行此操作而无需任何扩展,以便在启动时的初始 gdm 登录屏幕上、在活动登录会话中以及在会话解锁屏幕上始终可以看到自定义时间格式。这需要进行一些挖掘,但关键在于 Gnome 如何处理本地化/国际化以及 Gnome 挂钟如何获得字符串以实际显示在顶部栏中。

首先,可以在此处找到有关在 Gnome 本地化/国际化中使用 .po 和 .mo 文件的一些背景知识:

https://wiki.gnome.org/TranslationProject/LocalisationGuide

基本上,在运行时,Gnome 挂钟采用当前时间并应用本地化/国际化字符串格式。它使用一个字符串键来查找格式化字符串使用一个给定的语言环境来确定实际显示什么-它依赖于区域设置文件格式的字符串。如果修改本地化/国际化文件中给定键的返回值,时钟显示将反映更改。本地化/国际化使用两个文件。第一个是翻译人员为每个语言环境填充的人类可读的 .po 文件,这是可以找到从查找键到格式化字符串的映射的地方。第二个是从 .po 文件生成的 .mo 文件......更多关于这个以及它如何相关......

以下是 Ubuntu 18.04 中使用的 Gnome 挂钟版本源的链接:

https://github.com/GNOME/gnome-desktop/blob/gnome-3-28/libgnome-desktop/gnome-wall-clock.c

如果您检查从第 261 行开始的函数“gnome_wall_clock_string_for_datetime”,您将看到正在使用的本地化/国际化查找键。有几种。Ubuntu 有各种挂钟显示设置,具体取决于您是否只想显示时间、日期时间、日期时间和日期等。这些设置中的每一个都对应于挂钟使用的给定本地化/国际化查找键。您在下面的引号中看到的不是格式字符串本身,而是查找实际格式字符串的关键。围绕每个键的 _() 执行查找:

char *
gnome_wall_clock_string_for_datetime (GnomeWallClock      *self,
                      GDateTime           *now,
                      GDesktopClockFormat  clock_format,
                      gboolean             show_weekday,
                      gboolean             show_full_date,
                      gboolean             show_seconds)
{
    const char *format_string;

    if (clock_format == G_DESKTOP_CLOCK_FORMAT_24H) {
        if (show_full_date) {
            /* Translators: This is the time format with full date used
               in 24-hour mode. */
            format_string = show_seconds ? _("%a %b %e, %R:%S")
                : _("%a %b %e, %R");
        } else if (show_weekday) {
            /* Translators: This is the time format with day used
               in 24-hour mode. */
            format_string = show_seconds ? _("%a %R:%S")
                : _("%a %R");
        } else {
            /* Translators: This is the time format without date used
               in 24-hour mode. */
            format_string = show_seconds ? _("%R:%S") : _("%R");
        }
    } else {
        if (show_full_date) {
            /* Translators: This is a time format with full date used
               for AM/PM. */
            format_string = show_seconds ? _("%a %b %e, %l:%M:%S %p")
                : _("%a %b %e, %l:%M %p");
        } else if (show_weekday) {
            /* Translators: This is a time format with day used
               for AM/PM. */
            format_string = show_seconds ? _("%a %l:%M:%S %p")
                : _("%a %l:%M %p");
        } else {
            /* Translators: This is a time format without date used
               for AM/PM. */
            format_string = show_seconds ? _("%l:%M:%S %p")
                : _("%l:%M %p");
        }
    }

    return date_time_format (now, format_string);
}
Run Code Online (Sandbox Code Playgroud)

例如,我想要一个自定义格式字符串,用于以 12 小时格式显示日期、日期和时间。那是在 Ubuntu 中,我已将时钟设置为以 12 小时格式显示日期、日期和时间,这对应于上述代码中的“完整日期”。检查该函数,我能够确定这个“完整日期”查找键发生在第 288 行:

/* Translators: This is a time format with full date used
   for AM/PM. */
format_string = show_seconds ? _("%a %b %e, %l:%M:%S %p")
        : _("%a %b %e, %l:%M %p");
Run Code Online (Sandbox Code Playgroud)

我对秒不感兴趣,所以我需要在本地化/国际化 .po 文件中找到的关键是:

'%a %b %e, %l:%M %p'
Run Code Online (Sandbox Code Playgroud)

本地化/国际化 .mo 文件是二进制格式,但很容易从人类可读的纯文本映射 .po 文件生成,该文件将给定的查找键映射到格式化字符串。Gnome 挂钟使用特定名称为 gnome-desktop-3.0.mo 的文件进行本地化/国际化。在任何语言环境的规定位置下,它存在于我的系统上:

/usr/share/locale/XX/LC_MESSAGES
Run Code Online (Sandbox Code Playgroud)

所以,我不需要担心替换它,而是重新创建它。无论如何,您需要首先为您的语言环境获取 .po 文件:

https://github.com/GNOME/gnome-desktop/tree/gnome-3-28/po

接下来,找到上面提到的特定键(或其中的关键,你要根据在Ubuntu的时钟设置更改格式字符串)在.po文件。字符串键是'msgid',要返回的格式化字符串是'msgstr'。例如,我的 .po 文件中的片段是(忽略他们的评论,因为代码行实际上并不匹配):

#: ../libgnome-desktop/gnome-wall-clock.c:316
msgid "%a %b %e, %l:%M %p"
msgstr "%a %b %e, %l:%M %p"
Run Code Online (Sandbox Code Playgroud)

修改后:

#: ../libgnome-desktop/gnome-wall-clock.c:316
msgid "%a %b %e, %l:%M %p"
msgstr "%A %b %-d, %l:%M %p"
Run Code Online (Sandbox Code Playgroud)

在上述 'msgstr' 中反映的更改之前,它将显示:

Mon Feb  4, 12:22 PM
Run Code Online (Sandbox Code Playgroud)

但是在上述更改之后,日期不再缩写并且日期前面的前导空格已被删除(有关格式说明符,请参阅此答案的结尾):

Monday Feb 4, 12:22 PM
Run Code Online (Sandbox Code Playgroud)

接下来,获取这个 .po 文件并通过以下命令行运行它以获取 messages.mo 文件,其中 XX 是您的语言环境。二进制 msgfmt 已经安装在 Ubuntu 18.04 上:

msgfmt -cv XX.po
Run Code Online (Sandbox Code Playgroud)

接下来,将生成的 messages.mo 文件重命名为 gnome-desktop-3.0.mo 并将其复制到您的特定语言环境 LC_MESSAGE 目录:

/usr/share/locale/XX/LC_MESSAGES/gnome-desktop-3.0.mo
Run Code Online (Sandbox Code Playgroud)

然后,以实现变革,注销并重新登录。如果您发现该格式并没有改变,然后仔细检查你当前的时钟设置真正对应于你改变了格式化字符串的关键。

最后,这里有一些格式化字符串说明符可以帮助您。我从另一个网站借用了这些,所以不能保证这些在 Gnome 中工作:

The % sign indicating a directive may be immediately followed by a padding modifier, e.g. %-d:

0 - zero-padding
_ - space-padding
- - disable padding

%a - abbreviated weekday name.*
%A - full weekday name.*
%b - abbreviated month name.*
%B - full month name.*
%d - zero-padded day of the month as a decimal number [01,31].
%e - space-padded day of the month as a decimal number [ 1,31]; equivalent to %_d.
%f - microseconds as a decimal number [000000, 999999].
%H - hour (24-hour clock) as a decimal number [00,23].
%I - hour (12-hour clock) as a decimal number [01,12].
%j - day of the year as a decimal number [001,366].
%m - month as a decimal number [01,12].
%M - minute as a decimal number [00,59].
%L - milliseconds as a decimal number [000, 999].
%p - either AM or PM.*
%Q - milliseconds since UNIX epoch.
%s - seconds since UNIX epoch.
%S - second as a decimal number [00,61].
%u - Monday-based (ISO 8601) weekday as a decimal number [1,7].
%U - Sunday-based week of the year as a decimal number [00,53].
%V - ISO 8601 week of the year as a decimal number [01, 53].
%w - Sunday-based weekday as a decimal number [0,6].
%W - Monday-based week of the year as a decimal number [00,53].
%x - the locale’s date, such as %-m/%-d/%Y.*
%X - the locale’s time, such as %-I:%M:%S %p.*
%y - year without century as a decimal number [00,99].
%Y - year with century as a decimal number.
%Z - time zone offset, such as -0700, -07:00, -07, or Z.
%% - a literal percent sign (%).
Run Code Online (Sandbox Code Playgroud)