11

Is there any way for a bash script to look up the name of the current workspace (virtual desktop)?

This seems really useful for things like customizing behaviors in my .bashrc file based on the desktop in which the shell was created.

Jacob Vlijm
  • 85,475
DonGar
  • 213

3 Answers3

15

You can do it with wmctrl -d to list all workspaces. The * represents the current workspace:

~$ wmctrl -d
0  * DG: 3840x1080  VP: 0,0  WA: 0,25 3840x1055  1
1  - DG: 3840x1080  VP: N/A  WA: 0,25 3840x1055  2
2  - DG: 3840x1080  VP: N/A  WA: 0,25 3840x1055  3
3  - DG: 3840x1080  VP: N/A  WA: 0,25 3840x1055  4

So, to get only the current, grep for the *:

~$ wmctrl -d | grep -w '*'
0  * DG: 3840x1080  VP: 0,0  WA: 0,25 3840x1055  1

Hope this helps!

Terrance
  • 43,712
12

Viewports in Unity

If you are using Unity, the current viewport cannot be retrieved directly from

wmctrl -d

since Unity has viewports, which are not detected directly by wmctrl -d. The output will show only one workspace:

0  * DG: 5040x2100  VP: 1680,1050  WA: 59,24 1621x1026  N/A
  • where my resolution is 1680 x 1050 (from xrandr)
  • the spanning workspace (all viewports) is 5040x2100. That is 3x2 viewports: 5040/1680 = 3 and 2100 / 1050 = 2.
  • I am currently on (viewport-) position 1680,1050 (x,y)

The script below calculates the current viewport from this information:

#!/usr/bin/env python3
import subprocess

def get_res():
    # get resolution
    xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
    pos = xr.index("current")
    return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]

def current():
    # get the resolution (viewport size)
    res = get_res()
    # read wmctrl -d
    vp_data = subprocess.check_output(
        ["wmctrl", "-d"]
        ).decode("utf-8").split()
    # get the size of the spanning workspace (all viewports)
    dt = [int(n) for n in vp_data[3].split("x")]
    # calculate the number of columns
    cols = int(dt[0]/res[0])
    # calculate the number of rows
    rows = int(dt[1]/res[1])
    # get the current position in the spanning workspace
    curr_vpdata = [int(n) for n in vp_data[5].split(",")]
    # current column (readable format)
    curr_col = int(curr_vpdata[0]/res[0])
    # current row (readable format)
    curr_row = int(curr_vpdata[1]/res[1])
    # calculate the current viewport
    return curr_col+curr_row*cols+1

print(current())

To use:

  1. Install wmctrl

    sudo apt install wmctrl
    
  2. Run it by the command

    python3 /path/to/get_viewport.py
    

    It will output 1, 2, 3, or whatever the current viewport is. It automatically counts rows/columns your viewport configuration may include.

Explanation

enter image description here

The script

  • gets the size of one viewport (resolution) from xrandr, including possible extra monitors.
  • gets the current position on the spanning workspace
  • galculates the number of columns /rows in your viewport setup
  • from that, it calculates the current viewport
Jacob Vlijm
  • 85,475
3

At least in Gnome shell, but probably in other WM too, you can ask the Xserver directly (if in Wayland, no idea).

[romano:~/tmp] % desktop=$(xprop -root -notype  _NET_CURRENT_DESKTOP | perl -pe 's/.*?= (\d+)/$1/') 
[romano:~/tmp] % echo $desktop
1

Basically, the command xprop will return

 [romano:~/tmp] % xprop -root -notype  _NET_CURRENT_DESKTOP
 _NET_CURRENT_DESKTOP = 1

and then you can massage a bit the info to get what you need.

Rmano
  • 32,167