Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Grab wmclass name or Window Name/Title under Wayland with Gnome 3.x
# Single Command, runs 2 calls to gdbus to get the currently active Window from Gnome 3.x
# Escaped so you can copy and paste into terminal directly
gdbus call -e -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval global.get_window_actors\(\)[`gdbus call -e -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval global.get_window_actors\(\).findIndex\(a\=\>a.meta_window.has_focus\(\)===true\) | cut -d"'" -f 2`].get_meta_window\(\).get_wm_class\(\) | cut -d'"' -f 2
# Unescaped version, will not run
# Broken down into 2 commands.
# Call to Gnome to get the array location of the active Application
gdbus call -e -d org.gnome.Shell -o /org/gnome/Shell -m \
org.gnome.Shell.Eval global.get_window_actors().findIndex(a=>a.meta_window.has_focus()===true) \
| cut -d"'" -f 2
# Replace the array number 2 with the one from the previous command and you will get the App Name of the actively focused Window
gdbus call -e -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval \
global.get_window_actors()[2].get_meta_window().get_wm_class() \
| cut -d'"' -f 2
@rbreaves

This comment has been minimized.

Copy link
Owner Author

@rbreaves rbreaves commented Jan 24, 2020

Will also make note that this may be a similar alternative on how to do this under KDE.

https://unix.stackexchange.com/questions/385697/how-do-i-run-a-kwin-script-from-the-console-to-set-focus-to-a-specific-window-i

@johan-bjareholt

This comment has been minimized.

Copy link

@johan-bjareholt johan-bjareholt commented Jan 24, 2020

Note that there's also the possibility for race conditions (the user closing the window between call 1 and call 2), so don't expect this to always work.

@rbreaves

This comment has been minimized.

Copy link
Owner Author

@rbreaves rbreaves commented Jan 24, 2020

Yea, I have noticed that the inner or 1st call can also fail if you're in a state between applications as the DE knows the new active window or app is not ready and yet the old one is already non-active so you are left with a 1st call that comes back with nothing. It could be written better to try and avoid that.

@RaghavRao

This comment has been minimized.

Copy link

@RaghavRao RaghavRao commented Mar 16, 2020

Is there a way to re-activate the window retrieved from here?

@rbreaves

This comment has been minimized.

Copy link
Owner Author

@rbreaves rbreaves commented Mar 16, 2020

@RaghavRao You can probably work something out by looking at this thread, they limit alt+tab to only the apps on a particular active monitor - but considering they're able to limit the Windows via a filter for alt+tab.. I would think you might be able to modify the code in some way to simply activate a particular Window/App however you want, but I am not entirely sure.

You may be able to use d-feet or some app to help you dump/view the methods available as well.

https://unix.stackexchange.com/questions/281670/restrict-alttab-to-the-current-monitor-in-gnome-3

For my own purpose I don't need to re-activate an app or window as my own app will only ever monitor the app the user has currently selected. Anything beyond that, for me, is not needed.

@mccabeservant

This comment has been minimized.

Copy link

@mccabeservant mccabeservant commented Apr 8, 2020

This was very helpful for me! Thank you!

I was easily able to write a second query identical to the first, substituting only get_title() for get_wm_class() to get the title of the currently open webpage in Firefox, Opera, or Chromium as well as the app name, while knowing virtually nothing about bash scripting.

However, if .get_wm_class() (or get_title()) is a string with an apostrophe or double-quote character, the name of the app will get messed up. I had to remove | cut -d'"' -f 2 from the end of your command to get something I found usable, which I was then able to parse in the python app that I was actually using your command in. FWIW, here are the basics of the python code I used (in case someone else happens to be in a similar boat)...

import subprocess
import ast

app_command = ("gdbus call -e -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval global.get_window_actors\(\)[`gdbus call -e -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval global.get_window_actors\(\).findIndex\(a\=\>a.meta_window.has_focus\(\)===true\) | cut -d\"'\" -f 2`].get_meta_window\(\).get_wm_class\(\)")
app_process = subprocess.Popen(app_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
app_retval = app_process.stdout.read()
app_retcode = app_process.wait()

app_tuple_string = app_retval.decode('utf-8').strip()
# We now have a string that looks like:
# (true, "\"Qur'an App"\")

app_tuple_string = app_tuple_string.replace("(true", "(True")
app_tuple_string = app_tuple_string.replace("(false", "(False")
# We now have a string that looks like a python tuple:
# (True, "\"Qur'an App"\")

app_tuple = ast.literal_eval(app_tuple_string)
app = app_tuple[1]
# We now have a string with quotes in it that looks like:
# "Qur'an App"

app = ast.literal_eval(app)
# We now have a string that looks like:
# Qur'an App

print(app)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.