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

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

我有一个非常具体的问题,我一直没有找到可行的解决方案。我有一台运行 Ubuntu 18.04 的笔记本电脑,使用 2 个外接显示器对接,从而产生 3 个屏幕。我想在所有 3 个屏幕上显示我的顶部栏,以便轻松查看当前屏幕以查看时间。我使用多显示器附加组件Gnome 扩展。我运行的是英文版 Ubuntu,但设置为瑞典语格式。这导致顶部栏中的日期格式非常丑陋且不正确。

顶部栏时钟图片

这几乎是英语格式,但用瑞典语表示星期和月份的名称。顺便提一下,此本地化“错误”已修复并且已经为即将发布的 gnome 版本做好了准备。

我的主要问题是我想将显示的日期格式更改为类似以下内容:

所需格式的图像

我可以使用许多时钟格式 Gnome 扩展中的任何一个轻松获得此格式(时钟覆盖日期时间格式)。但是,这些扩展都无法与我的多显示器插件配合使用,导致主显示器上的时钟格式很好,而其他两个屏幕上的时钟格式却很丑陋。我尝试过这些附加组件的开发人员进行协作,但显然 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 更改多台显示器上显示的日期和时间格式?请随意尝试我已经尝试过的方法,因为我肯定会错过一些可以让它工作的东西。

答案1

BLUF:这是一种永久且干净的方法,可以根据您的喜好改变 Gnome 顶栏时钟的格式,而无需使用扩展。

我还想在 Gnome 顶栏中显示自定义格式的时钟字符串,但只显示一个。但是,这个答案也会扩展到您的问题,并允许您只使用多显示器顶栏扩展。我的目标是简单地执行此操作,而无需任何扩展,以便在启动时、在活动登录会话中以及在会话解锁屏幕上始终显示自定义时间格式。这需要一些挖掘,但关键在于 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);
}

例如,我想要一个自定义格式字符串,用于以 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");

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

'%a %b %e, %l:%M %p'

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

/usr/share/locale/XX/LC_MESSAGES

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

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

接下来,找到上面提到的具体的密钥(或密钥您可以在 .po 文件中指定要更改的格式字符串(例如,如果您想要根据 Ubuntu 中的时钟设置更改格式字符串)。字符串键是“msgid”,要返回的格式字符串是“msgstr”。例如,我的 .po 文件中的代码片段是(忽略它们的注释,因为代码行实际上并不匹配):

#: ../libgnome-desktop/gnome-wall-clock.c:316
msgid "%a %b %e, %l:%M %p"
msgstr "%a %b %e, %l:%M %p"

修改后:

#: ../libgnome-desktop/gnome-wall-clock.c:316
msgid "%a %b %e, %l:%M %p"
msgstr "%A %b %-d, %l:%M %p"

在上述“msgstr”反映出变化之前,它会显示:

Mon Feb  4, 12:22 PM

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

Monday Feb 4, 12:22 PM

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

msgfmt -cv XX.po

接下来,将生成的 messages.mo 文件重命名为 gnome-desktop-3.0.mo 并将其复制到你的特定区域设置的 LC_MESSAGE 目录:

/usr/share/locale/XX/LC_MESSAGES/gnome-desktop-3.0.mo

然后,为了使更改生效,请注销并重新登录。如果您发现格式确实不是更改然后仔细检查您当前的时钟设置是否真正与您更改格式字符串的键相对应。

最后,这里有一些格式化字符串说明符可以帮助您。我从另一个网站借用了这些,因此不能保证这些全部在 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 (%).

相关内容