30

I'm trying to make a quicklist on the Workspace Switcher launcher that allows for quick switching to a certain workspace. (My friend sometimes uses my computer and just doesn't enjoy keyboard shortcuts, so I want to help him out.)

So is there a command one could type in a terminal that would force a certain workspace to be focused on?

1
  • Also there is a possibility to set keyboard shortcut on systemsettings5 for kwin (switch desktop or else) or other desktop settings manager. then use xdotool to simulate the shortcut keys like xdotool key ctrl+alt+b;
    – intika
    Apr 22, 2019 at 1:45

6 Answers 6

46

You can use wmctrl.

Basics commands:
wmctrl -d to show all of your workspaces.
wmctrl -s <workspace_name> to change to a specific workspace.

If you are using Compiz, you will have to do a trick because Compiz "workspaces" are actually Viewports of a single Workspace.

Trick Instructions

Check the output of wmctrl -d For example, mine is:

0  * DG: 4098x2304  VP: 1366,0  WA: 0,23 1366x745  N/A  

This means that actually I have one Workspace of 4098 x 2304 instead of what I "think" I have (nine "workspaces", 3 x 3).
I was at what was supposed to be "workspace" 2, but actually I was at viewport (VP) 1366,0 (4098 / 3 = 1366) as showed by the output above.

So this is how it works: we take the whole Workspace and divide for the numbers of "workspaces" we "think" we have. In my case: 4098 / 3 = 1366 and 2304 / 3 = 768.

If I want to go to my "workspace" 1, the command is:

wmctrl -o 0,0

Then, if I want to go to my "workspace" 4, the command is:

wmctrl -o 0,768

If I want to go to my "workspace" 8, the command is:

wmctrl -o 1366,1536

If I want to go to my "workspace" 9, the command is:

wmctrl -o 2732,1536

Got it? ;-)

The -o flag "truncates" their values. In other words it changes the "workspace" where the actual pixel is belonging to. The following are equivalent:

wmctrl -o 0,0
wmctrl -o 1365,767
3
  • 2
    Is there a way to get to "the current desktop + 1"?
    – xjcl
    Apr 3, 2019 at 20:13
  • @xjcl You can do expr $(xdotool get_desktop) + 1 Apr 19, 2020 at 17:13
  • @Elijas One might as well use a pure xdotool solution in that case. Plus what happens on the last desktop?
    – xjcl
    May 5, 2020 at 12:16
17

It is beautifully simple to achieve what you want with xdotool, which has multiple options for managing different workspaces (also known as 'desktops' within the program documentation). I find it can be very interesting and creative to string together commands from man xdotool; the commands I have formulated below might be useful in scripts.

Note: With some window managers, or if you are using compiz, you may need to use xdotool commands such as set_desktop_viewport and get_desktop_viewport. You may have to specify the commands in a different way like desgua suggests above, but for me the set_desktop and set_desktop_for_window commands proved most useful on a non-compiz system.)

(The solution is most useful for Xubuntu/Lubuntu users, or those who are not running compiz,etc.)

To list the number of current workspaces, enter

xdotool get_num_desktops

The following commands will only work if you have at least 1 other workspace.

To change focus to your workspace 1, just enter

xdotool set_desktop 1 

Then to return to the default workspace, enter

xdotool set_desktop 0

The workspace just needs to be specified as the last value in the command (1 or 2 or 3, etc).

To find the number of the workspace you are currently on, you could use

xdotool get_desktop

These commands could be used in scripts and they should be very useful for achieving what you what.

For how to switch applications to a particular desktop, see my answer here:

For more useful options available for workspace switching, consult man xdotool.

2
  • I like this answer better than the accepted one, thank you. I used this to set two hot corners to easily switch between two workspaces.
    – timetofly
    Aug 8, 2013 at 20:00
  • 3
    Also useful: Switch to the next desktop to the left/right by using the relative flag: xdotool set_desktop --relative -- -1
    – xjcl
    Apr 3, 2019 at 20:23
1

I have implemented a script that does what you want. Here it is: https://github.com/norswap/wmov/blob/master/wmov.sh

It works indeed as described in desgua's post. It also the capabilities to send windows to other workspaces.

1
  • 1
    Note: Doesn't work for virtual-desktop counts > 9.
    – j6m8
    Jul 21, 2015 at 15:36
0

There is a script called compiz-send.py on the compiz wiki that partly adresses your question: it is not a specific workspace but you can get to the one next to it.

With this you can issue a command
./compiz-dbus-send.py put put_viewport_left_key
./compiz-dbus-send.py put put_viewport_right_key
and have the viewport go 1 to the left or to right.

0

Going to a specific workspace and performing actions there can be implemented with Python and the library pyautogui, that enables Python scripts to perform mouse clicks, keystrokes, etc.

I wrote a short tutorial in the forum for Peppermint OS about starting an app on a specific workplace.

0

Update for desgua's answer - seems wmctrl -d outputs differently for Ubuntu 18.04.

This provides shortcuts for first, last and new workspaces too, or as a function you can call __ws_switch N where N is the workspace number.

0  * DG: 1920x1080  VP: 0,0  WA: 0,28 1920x1052  Workspace 1
1  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052  Workspace 2
2  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052  Workspace 3
3  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052  Workspace 4
4  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052  Workspace 5
5  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052  Workspace 6
6  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052  Workspace 7
7  - DG: 1920x1080  VP: N/A  WA: 0,28 1920x1052

Note the final blank workspace that isn't currently used. Assuming by the last workspace we mean the last workspace that is in use, the following could work:

cat << EOF >> "$script_dir"/ws.sh
#!/bin/sh

__ws_count() {
  __ws_counter="$(wmctrl -d | wc -l)"
  echo "$(( __ws_counter - 1 ))"
}

__ws_switch() {
  # Sanity test if "$1" is an int
  case "$1" in ''|*[^0-9]*) 
    echo "Input '$1' is not an integer"
    return 1 ;; 
  esac

  if test "$1" -gt "$(__ws_count)"; then
    echo "Workspace #$1 doesn't exist"
    return 1
  fi

  wmctrl -s "$1"
}

__ws_first() {
  __ws_switch 0
}

__ws_last() {
  __ws_counter="$(__ws_count)"
  __ws_switch "$(( __ws_counter - 1 ))"
}

__ws_new() {
  __ws_counter="$(__ws_count)"
  __ws_switch "$(( __ws_counter ))"
}
EOF

To add as a shortcut using xbindkeys, create the following shortcut files:

cat << EOF >> "$script_dir"/ws_first.sh
#!/bin/sh

. ./ws.sh

__ws_first
EOF
cat << EOF >> "$script_dir"/ws_last.sh
#!/bin/sh

. ./ws.sh

__ws_last
EOF
cat << EOF >> "$script_dir"/ws_new.sh
#!/bin/sh

. ./ws.sh

__ws_new
EOF

Then chmod +x ./ws.sh ./ws_first.sh ./ws_last.sh ./ws_new.sh to make them executable. Finally, to add to .xbindkeysrc:

cat << EOF >> ~/.xbindkeysrc
"$script_dir/ws_first.sh"
  Alt + Alt_L + w + f

"$script_dir/ws_last.sh"
  Alt + Alt_L + w + l

"$script_dir/ws_new.sh"
  Alt + Alt_L + w + n
EOF

EDIT: Don't forget to restart xbindkeys for changes to take effect:

killall xbindkeys && xbindkeys
1
  • Note that the shortcuts in the above are alt + w + X where X is n for a new workspace, f for the first, l for the last
    – Nick Bull
    Jan 30, 2020 at 12:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .