Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate menu in macOS #10049

Open
yuantao313 opened this issue Nov 8, 2024 · 3 comments
Open

Translate menu in macOS #10049

yuantao313 opened this issue Nov 8, 2024 · 3 comments
Labels

Comments

@yuantao313
Copy link

Describe the problem:
In macOS, my language is Chinese, the menu is still shown in English while the main screen is shown in Chinese correctly.

To Reproduce:
Switch macOS to Chinese:
截屏2024-11-08 22 39 51

@piersandro
Copy link
Contributor

That menu is in English in all languages. It depends on Electron not on Tabby.

@DehanLUO
Copy link
Contributor

DehanLUO commented Nov 15, 2024

That menu is in English in all languages. It depends on Electron not on Tabby.

Thank you for your response. I’d like to offer a small clarification regarding the menu language in the top-left corner of macOS. It seems that this menu is not directly tied to Electron. From my investigation, I’ve found that it is possible to modify the language displayed in this menu by adjusting the following section of code:

tabby/app/lib/app.ts

Lines 247 to 330 in ac6f60f

private setupMenu () {
const template: MenuItemConstructorOptions[] = [
{
label: 'Application',
submenu: [
{ role: 'about', label: 'About Tabby' },
{ type: 'separator' },
{
label: 'Preferences',
accelerator: 'Cmd+,',
click: async () => {
if (!this.hasWindows()) {
await this.newWindow()
}
this.windows[0].send('host:preferences-menu')
},
},
{ type: 'separator' },
{ role: 'services', submenu: [] },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{
label: 'Quit',
accelerator: 'Cmd+Q',
click: () => {
this.quitRequested = true
app.quit()
},
},
],
},
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'pasteAndMatchStyle' },
{ role: 'delete' },
{ role: 'selectAll' },
],
},
{
label: 'View',
submenu: [
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'togglefullscreen' },
],
},
{
role: 'window',
submenu: [
{ role: 'minimize' },
{ role: 'zoom' },
{ type: 'separator' },
{ role: 'front' },
],
},
{
role: 'help',
submenu: [
{
label: 'Website',
click () {
shell.openExternal('https://eugeny.github.io/tabby')
},
},
],
},
]
if (process.env.TABBY_DEV) {
template[2].submenu['unshift']({ role: 'reload' })
}
Menu.setApplicationMenu(Menu.buildFromTemplate(template))
}

For example, I made the following changes to the code:

private setupMenu () {
    const template: MenuItemConstructorOptions[] = [
        {
            label: 'Application',
            submenu: [
                { role: 'about', label: '关于' },
                { type: 'separator' },
                {
                    label: '偏好设置',
                    accelerator: 'Cmd+,',
                    click: async () => {
                        if (!this.hasWindows()) {
                            await this.newWindow()
                        }
                        this.windows[0].send('host:preferences-menu')
                    },
                },
                { type: 'separator' },
                { role: 'services', label: '服务', submenu: [] },
                { type: 'separator' },
                { role: 'hide', label: '隐藏' },
                { role: 'hideOthers', label: '隐藏其他窗口' },
                { role: 'unhide', label: '显示全部' },
                { type: 'separator' },
                {
                    label: '退出',
                    accelerator: 'Cmd+Q',
                    click: () => {
                        this.quitRequested = true
                        app.quit()
                    },
                },
            ],
        },
        {
            label: '编辑',
            submenu: [
                { role: 'undo', label: '关于' },
                { role: 'redo', label: '重做' },
                { type: 'separator' },
                { role: 'cut', label: '剪切' },
                { role: 'copy', label: '复制' },
                { role: 'paste', label: '粘贴' },
                { role: 'pasteAndMatchStyle', label: '格式化粘贴' },
                { role: 'delete', label: '删除' },
                { role: 'selectAll', label: '全选' },
            ],
        },
        {
            label: '视图',
            submenu: [
                { role: 'toggleDevTools', label: '开发者工具' },
                { type: 'separator' },
                { role: 'togglefullscreen', label: '全屏' },
            ],
        },
        {
            role: 'window', label: '窗口',
            submenu: [
                { role: 'minimize' },
                { role: 'zoom' },
                { type: 'separator' },
                { role: 'front' },
            ],
        },
        {
            role: 'help', label: '帮助',
            submenu: [
                {
                    label: 'Website',
                    click () {
                        shell.openExternal('https://eugeny.github.io/tabby')
                    },
                },
            ],
        },
    ]

    if (process.env.TABBY_DEV) {
        template[2].submenu['unshift']({ role: 'reload', label: '重载' })
    }

    Menu.setApplicationMenu(Menu.buildFromTemplate(template))
}

And here’s a gif demonstrating the result:

screenshot

It seems that adding some additional logic to match the language settings and update the label accordingly could be an effective way to ensure the menu reflects the chosen language.

@DehanLUO
Copy link
Contributor

@yuantao313 Could you kindly confirm if this aligns with the intended outcome?

screenshot

Modification
private setupMenu () {
    function getEffectiveLocale () {
        const preferredLanguages = app.getPreferredSystemLanguages()
    if (preferredLanguages[0].startsWith('zh')) {
        return 'zh-CN'
    } else if (preferredLanguages[0].startsWith('en')) {
        return 'en'
    } else {
        return 'en'
    }
}
const locale = getEffectiveLocale()
const translations = {
    en: {
        about: 'About Tabby',
        preferences: 'Preferences',
        services: 'Services',
        hide: 'Hide',
        hideOthers: 'Hide Others',
        unhide: 'Show All',
        quit: 'Quit',
        edit: 'Edit',
        undo: 'Undo',
        redo: 'Redo',
        cut: 'Cut',
        copy: 'Copy',
        paste: 'Paste',
        pasteAndMatchStyle: 'Paste and Match Style',
        'delete': 'Delete',
        selectAll: 'Select All',
        view: 'View',
        toggleDevTools: 'Togggle Developer Tools',
        togglefullscreen: 'Toggle Full Screen',
        window: 'Window',
        reload: 'Reload',
        minimize: 'Minimize',
        zoom: 'Zoom',
        front: 'Bring All to Front',
        help: 'Help',
        website: 'Website',
    },
    'zh-CN': {
        about: '关于Tabby',
        preferences: '偏好设置',
        services: '服务',
        hide: '隐藏',
        hideOthers: '隐藏其他窗口',
        unhide: '显示全部',
        quit: '退出',
        edit: '编辑',
        undo: '撤销',
        redo: '重做',
        cut: '剪切',
        copy: '复制',
        paste: '粘贴',
        pasteAndMatchStyle: '格式化粘贴',
        'delete': '删除',
        selectAll: '全选',
        view: '视图',
        toggleDevTools: '开发者工具',
        togglefullscreen: '全屏',
        window: '窗口',
        reload: '重载',
        minimize: '最小化',
        zoom: '缩放',
        front: '前置所有窗口',
        help: '帮助',
        website: '网站',
    },
}
const t = translations[locale]
const template: MenuItemConstructorOptions[] = [
    {
        label: 'Application',
        submenu: [
            { role: 'about', label: t.about },
            { type: 'separator' },
            {
                label: t.preferences,
                accelerator: 'Cmd+,',
                click: async () => {
                    if (!this.hasWindows()) {
                        await this.newWindow()
                    }
                    this.windows[0].send('host:preferences-menu')
                },
            },
            { type: 'separator' },
            { role: 'services', label: t.services, submenu: [] },
            { type: 'separator' },
            { role: 'hide', label: t.hide },
            { role: 'hideOthers', label: t.hideOthers },
            { role: 'unhide', label: t.unhide },
            { type: 'separator' },
            {
                label: t.quit,
                accelerator: 'Cmd+Q',
                click: () => {
                    this.quitRequested = true
                    app.quit()
                },
            },
        ],
    },
    {
        label: t.edit,
        submenu: [
            { role: 'undo', label: t.undo },
            { role: 'redo', label: t.redo },
            { type: 'separator' },
            { role: 'cut', label: t.cut },
            { role: 'copy', label: t.copy },
            { role: 'paste', label: t.paste },
            { role: 'pasteAndMatchStyle', label: t.pasteAndMatchStyle },
            { role: 'delete', label: t.delete },
            { role: 'selectAll', label: t.selectAll },
        ],
    },
    {
        label: t.view,
        submenu: [
            { role: 'toggleDevTools', label: t.toggleDevTools },
            { type: 'separator' },
            { role: 'togglefullscreen', label: t.togglefullscreen },
        ],
    },
    {
        role: 'window', label: t.window,
        submenu: [
            { role: 'minimize', label: t.minimize },
            { role: 'zoom', label: t.zoom },
            { type: 'separator' },
            { role: 'front', label: t.front },
        ],
    },
    {
        role: 'help', label: t.help,
        submenu: [
            {
                label: t.website,
                click () {
                    shell.openExternal('https://eugeny.github.io/tabby')
                },
            },
        ],
    },
]

if (process.env.TABBY_DEV) {
    template[2].submenu['unshift']({ role: 'reload', label: t.reload })
}

Menu.setApplicationMenu(Menu.buildFromTemplate(template))

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants