如何检测 Crostini 中的活动 window?
How can I detect the active window in Crostini?
我想在 Chromebook 的 Linux Crostini 中以编程方式检测活动 window 及其元数据(如应用程序名称和标题)。有谁知道如何可靠地做到这一点?
FWIW,我已经在 python 中尝试了以下三种方法,它们结合使用后可为 Fedora、Ubuntu、Arch、Manjaro、Mint 等提供完整的解决方案。但是none 他们在 Crostini 上工作。
def getAppAndTitle():
title = ''
app = ''
try:
# METHOD 1: Try to get window id info from _NET_ACTIVE_WINDOW
actives = []
try:
actives = re.findall('0x([0-9a-fA-F]+)', subprocess.check_output("xprop -root _NET_ACTIVE_WINDOW", shell=True).decode('utf-8'))
except:
pass
if len(actives) > 0:
active_id = int(actives[0], 16)
if active_id != 0:
window_strs = ''
# Get the list of all window names & ids
try:
window_strs = subprocess.check_output("wmctrl -lx", shell=True).decode('utf-8')
except:
pass
for window_str in window_strs.splitlines():
acceptable = re.search('^0x([0-9a-fA-F]+)\s+\S+\s+(\S+)\s+\S+\s+(.*)$', window_str)
if acceptable:
acceptable_id = int(acceptable.group(1), 16)
if acceptable_id == active_id:
app, title = acceptable.group(2).strip(), acceptable.group(3).strip()
except Exception as e1:
pass
try:
# METHOD 2: Try to get window info from Wnck
if not (title and app):
screen = None
try:
screen = Wnck.Screen.get_default()
except Exception as e2:
pass
if screen:
screen.force_update()
active_window = screen.get_active_window()
if active_window:
title = active_window.get_name().strip()
app = active_window.get_application().get_name().strip()
except Exception as e1:
pass
try:
# METHOD 3: Designed for Wayland
if not (title and app):
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"\")
if app_tuple_string:
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:
# (True, "\"Qur'an App"\")
app_tuple = ast.literal_eval(app_tuple_string)
if len(app_tuple) > 1:
app = app_tuple[1]
# We now have a string that looks like:
# "Qur'an App"
if app and isinstance(app, str) and (type(app) is str):
app = app.strip()
if len(app) > 2:
if (app[0:1] == '"' and app[-1] == '"') or (app[0:1] == "'" and app[-1] == "'"):
app = ast.literal_eval(app).strip()
# We now have a string that looks like:
# Qur'an App
title_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_title\(\)")
title_process = subprocess.Popen(title_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
title_retval = title_process.stdout.read()
title_retcode = title_process.wait()
title_tuple_string = title_retval.decode('utf-8').strip()
if title_tuple_string:
title_tuple_string = title_tuple_string.replace("(true", "(True")
title_tuple_string = title_tuple_string.replace("(false", "(False")
title_tuple = ast.literal_eval(title_tuple_string)
if len(title_tuple) > 1:
title = title_tuple[1]
if title and isinstance(title, str) and (type(title) is str):
title = title.strip()
if len(title) > 2:
if (title[0:1] == '"' and title[-1] == '"') or (title[0:1] == "'" and title[-1] == "'"):
title = ast.literal_eval(title)
if "error:" in app.lower():
title = ''
app = ''
except Exception as e1:
title = ''
app = ''
return app, title
对其他方法有什么想法吗?
我已经能够使用以下两个终端命令完成此操作。
第一个得到运行windows的树。
xwininfo -root -tree
第二个告诉我哪些是重点。
xdpyinfo | grep focus
我想在 Chromebook 的 Linux Crostini 中以编程方式检测活动 window 及其元数据(如应用程序名称和标题)。有谁知道如何可靠地做到这一点?
FWIW,我已经在 python 中尝试了以下三种方法,它们结合使用后可为 Fedora、Ubuntu、Arch、Manjaro、Mint 等提供完整的解决方案。但是none 他们在 Crostini 上工作。
def getAppAndTitle():
title = ''
app = ''
try:
# METHOD 1: Try to get window id info from _NET_ACTIVE_WINDOW
actives = []
try:
actives = re.findall('0x([0-9a-fA-F]+)', subprocess.check_output("xprop -root _NET_ACTIVE_WINDOW", shell=True).decode('utf-8'))
except:
pass
if len(actives) > 0:
active_id = int(actives[0], 16)
if active_id != 0:
window_strs = ''
# Get the list of all window names & ids
try:
window_strs = subprocess.check_output("wmctrl -lx", shell=True).decode('utf-8')
except:
pass
for window_str in window_strs.splitlines():
acceptable = re.search('^0x([0-9a-fA-F]+)\s+\S+\s+(\S+)\s+\S+\s+(.*)$', window_str)
if acceptable:
acceptable_id = int(acceptable.group(1), 16)
if acceptable_id == active_id:
app, title = acceptable.group(2).strip(), acceptable.group(3).strip()
except Exception as e1:
pass
try:
# METHOD 2: Try to get window info from Wnck
if not (title and app):
screen = None
try:
screen = Wnck.Screen.get_default()
except Exception as e2:
pass
if screen:
screen.force_update()
active_window = screen.get_active_window()
if active_window:
title = active_window.get_name().strip()
app = active_window.get_application().get_name().strip()
except Exception as e1:
pass
try:
# METHOD 3: Designed for Wayland
if not (title and app):
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"\")
if app_tuple_string:
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:
# (True, "\"Qur'an App"\")
app_tuple = ast.literal_eval(app_tuple_string)
if len(app_tuple) > 1:
app = app_tuple[1]
# We now have a string that looks like:
# "Qur'an App"
if app and isinstance(app, str) and (type(app) is str):
app = app.strip()
if len(app) > 2:
if (app[0:1] == '"' and app[-1] == '"') or (app[0:1] == "'" and app[-1] == "'"):
app = ast.literal_eval(app).strip()
# We now have a string that looks like:
# Qur'an App
title_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_title\(\)")
title_process = subprocess.Popen(title_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
title_retval = title_process.stdout.read()
title_retcode = title_process.wait()
title_tuple_string = title_retval.decode('utf-8').strip()
if title_tuple_string:
title_tuple_string = title_tuple_string.replace("(true", "(True")
title_tuple_string = title_tuple_string.replace("(false", "(False")
title_tuple = ast.literal_eval(title_tuple_string)
if len(title_tuple) > 1:
title = title_tuple[1]
if title and isinstance(title, str) and (type(title) is str):
title = title.strip()
if len(title) > 2:
if (title[0:1] == '"' and title[-1] == '"') or (title[0:1] == "'" and title[-1] == "'"):
title = ast.literal_eval(title)
if "error:" in app.lower():
title = ''
app = ''
except Exception as e1:
title = ''
app = ''
return app, title
对其他方法有什么想法吗?
我已经能够使用以下两个终端命令完成此操作。
第一个得到运行windows的树。
xwininfo -root -tree
第二个告诉我哪些是重点。
xdpyinfo | grep focus