6

I'm using multiple keyboard layout - en, cs, no, zh I'd like to switch between using different shortcut for each, e.g.

  • Ctrl-Shift-1 - English
  • Ctrl-Shift-2 - Czech
  • Ctrl-Shift-3 - Norwegian
  • Ctrl-Shift-4 - Chinese

This way I can switch between the layouts very fast without keeping track what layout I'm actually using as it would be with Opt-Space cycling switch.

With 20.04 I was using the following script, but it seems it is not working in 22.04

gdbus call --session --dest org.gnome.Shell \                      
 --object-path /org/gnome/Shell \
 --method org.gnome.Shell.Eval \
 "imports.ui.status.keyboard.getInputSourceManager().inputSources[$1]"

Any idea how to achieve the same thing in the latest release?

6 Answers6

2

Update May, 2025:

Instead of the mentioned gnome extension install the shyriiwook extension from the official gnome extensions home page. According to its description this is safer as it exposes only that part of the JS api that is needed to change languages programmatically. Then you can skip steps 2-6. You only need to update your scripts.

First query your available layouts with:

gdbus introspect --session --dest org.gnome.Shell --object-path /me/madhead/Shyriiwook --only-properties

Then activate a desired layout, eg "us":

gdbus call --session --dest org.gnome.Shell --object-path /me/madhead/Shyriiwook --method me.madhead.Shyriiwook.activate "us"

I have managed to make this work inspired by the other answers. Unfortunately they were lacking some detail so instead will summarize the steps here for assigning keyboard shortcuts to a keyboard layout:

  1. Make sure you already have installed all the desired keyboard layouts. They should be shown in the top bar when clicking the language button.

  2. Download GNOME extension Eval-GJs: This extension is not on 'extensions.gnome.org', the official Gnome Shell Extensions website, so you must download / clone the repo from github.

  3. Install the extension as a regular user as described in its README.md:

cd eval-gjs-main
make install

This will copy it to a folder within your home directory: ~/.local/share/gnome-shell/extensions

  1. Determine your gnome version by executing:
gnome-shell --version
  1. Edit metadata.json in ~/.local/share/gnome-shell/extensions/eval-gjs@ramottamado.dev/

Insert your exact gnome version in the array after the line "shell-version".

Log out, then log in again.

  1. Launch Extension manager (gnome-extensions-app) Install it if you don't have it, with:
sudo apt install gnome-shell-extension-prefs
  1. Enable the extension. Note: the extension will not show up if your exact gnome version is not in metadata.json as explained above.

  2. Create the following bash script change-layout.sh and give it execute permissions :

#!/bin/bash
gsettings set org.gnome.desktop.input-sources current "$1" 
gdbus call --session --dest org.gnome.Shell \
--object-path /dev/ramottamado/EvalGjs \
--method dev.ramottamado.EvalGjs.Eval \
"imports.ui.status.keyboard.getInputSourceManager().inputSources[$1].activate()"
  1. Test the script. Run
change-layout.sh 0

for the first keyboard layout, in the case of OP this is English,

change-layout.sh 1

for the second layout, etc.

  1. Go to Gnome settings -> Keyboard -> View and Customize shortcuts -> Custom Shortucts, then assign your desire keyboard shortcut and use one of the commands above for the desired keyboard layout.
1mi
  • 419
1

You may be missing the activate() part of the command:

gdbus call --session --dest org.gnome.Shell \
--object-path /org/gnome/Shell \
--method org.gnome.Shell.Eval \
 "imports.ui.status.keyboard.getInputSourceManager().inputSources[$1].activate()"
vanadium
  • 98,427
  • 2
    yes, right, when I ad the activate it prints out the following: (false, '') but does not change the layout unfortunately – Pavel P.F. May 06 '22 at 15:26
0

First the problem is that as of GNOME 41, the dbus method Eval() is now restricted with MetaContext:unsafe-mode property (see this commit).

Solution that worked for me:

  1. Install GNOME extension Eval-GJs - This extension provides unrestricted Eval() dbus method for running arbitrary code in the compositor.
  2. rewrite the layout switching script to use the above extension
gdbus call --session --dest org.gnome.Shell \
--object-path /dev/ramottamado/EvalGjs \
--method dev.ramottamado.EvalGjs.Eval \
"imports.ui.status.keyboard.getInputSourceManager().inputSources[$1].activate()"
  • 1
    I installed the exension as described, but I get Error: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: Object does not exist at path “/dev/ramottamado/EvalGjs”. What can I do next? – 1mi Sep 07 '22 at 18:50
  • Instead of using a custom Eval, why not use the Quick Lang Switch Gnome-shell extension which simply skips the popup and switches languages instantaneously, without affecting any shortcuts, so setxkbd, gnome-tweak-tool, Wayland & X11 all continue to work fine? – ankostis Jul 29 '23 at 23:05
  • @1mi gnome-extensions enable eval-gjs@ramottamado.dev helped me. Don't forget to relogin after installing the extension and before running the above mentioned command. – RobinBobin Nov 28 '23 at 11:58
0

Wow, that was a solution for me (clean Ubuntu 22.04). A few notes: update metadata.json file (https://github.com/ramottamado/eval-gjs/pull/1) and install gnome-shell-extension-manager and then enable that extension.

Serge
  • 1
  • The extension is in my .local/share/gnome-shell/extensions/ folder and metadata.json is as in the mentioned commit. I have Gnome Shell 42.4, however Extension Manager doesn't show it. How can I enable it? – 1mi Sep 11 '22 at 18:39
0

I created GNOME extension to switch among 4 input methods directly. Since pertinent javascript code is executed without shell command gdbus, this doesn't require to use unsafe-mode.

Now, shortcuts are configurable.

0

Suffer no more! I've made a simple GNOME Shell Extension and I'm sharing it with the world: Shyriiwook (also available @ GitHub: madhead/shyriiwook).

This is a very simple, minimalist extension. It doesn't have any GUI. After installing it, a new D-Bus interface would be exposed in your GNOME Shell session. You could query it for the current configuration or call a method to activate the desired layout:

$ gdbus introspect \
    --session \
    --dest org.gnome.Shell \
    --object-path /me/madhead/Shyriiwook \
    --only-properties

node /me/madhead/Shyriiwook { interface me.madhead.Shyriiwook { properties: readonly as availableLayouts = ['us', 'de', 'jp']; readonly s currentLayout = 'us'; }; };

$ gdbus call
--session
--dest org.gnome.Shell
--object-path /me/madhead/Shyriiwook
--method me.madhead.Shyriiwook.activate "de"

This is easily scriptable, and you can even put this command raw into a custom shortcut under the "Settings" → "Keyboard" → "Keyboard Shortcuts" → "View and Customise Shortcuts" → "Custom Shortcuts".

What's interesting about it, is that Shyriiwook is based on D-Bus, but it doesn't use unsafe and deprecated Eval nor any of its alternatives. It re-implements a similar solution using GJS by accessing the same getInputSourceManager directly.

madhead
  • 722