当前,TeXstudio 窗口的名称是 /home/foo/bar.tex - TeXstudio,在任务栏上缩写为 /home/foo...;我觉得这很烦人,因为它非常不具描述性。
有没有办法改变 TeXstudio 命名窗口的方式?理想情况下,我希望窗口名为 bar.tex - TeXstudio。
答案1
将以下代码保存为 update_window_title_v1.0.py,使其可执行并在后台运行:
#!/usr/bin/python3
"""
Rename X11 windows if they have too long names
Written by Z J Laczik
Modify the following defines to fine tune behaviour :
src_pattern = r"/.+/"
replacement = "/.../"
limit = 16
period = 2
N.B. Be careful modifying src_pattern and replacement!
Wrong choice may result in the modification of all window names,
setting window names to '', or ending up with infinitely long
window names ptoentially crashing your window manager.
Change log
Date: 20220609 Version: 1.0
First release
"""
import time
import re
from Xlib import display
# change debug to True to enable debug messages
debug = False
# debug = True
def get_window_name( window ) :
# try and get utf-8 window name first, if that fails, try and get legacy name
for ( atom, prop_type ) in ( ( NET_WM_NAME, UTF8_STRING), ( WM_NAME, STRING ) ) :
try :
prop = window.get_full_property( atom, prop_type )
except UnicodeDecodeError :
window_name = "<could not decode characters>"
else :
# check whether get_full_property was succesful
# if not, set default name and try next atom
if prop :
# extract value data from property object
window_name = prop.value
# at this point window_name should be a string or a byte array
# it it is bytes then convert to string
if isinstance( window_name, bytes ) :
if ( atom == NET_WM_NAME ) :
# decode bytes as UTF-8
window_name = window_name.decode( 'utf-8', 'replace' )
else :
# decode bytes as ASCII
window_name = window_name.decode( 'ascii', 'replace' )
return window_name
else :
# set default return value
window_name = "<unnamed window>"
# we should only get here if neither atoms worked, hence return default
return window_name
def set_window_name( window, name ) :
try :
# set UTF-8 window name
window.change_property( NET_WM_NAME, UTF8_STRING, 8, name.encode( 'utf-8', 'replace' ) )
# set legacy ASCII name
window.change_property( WM_NAME, STRING, 8, name.encode( 'ascii', 'replace' ) )
except :
pass
def check( window, src_pattern = r"/.+/", replacement = "/.../", limit = 16 ) :
# get list of child windows
window_list = window.query_tree().children
# check each child window
for window in window_list :
# get current window name
old_name = get_window_name( window )
# check if length is above limit and if it matches replacement regex
if ( len( old_name ) > limit ) :
( new_name, matches ) = re.subn( src_pattern, replacement, old_name );
if ( matches > 0 and new_name != old_name ) :
set_window_name( window, new_name )
if debug :
print( "> Replaced '%s' with '%s'" % ( old_name, new_name ) )
# recursively check child windows below current window
check( window, src_pattern, replacement, limit )
# get display and root window
dsp = display.Display()
root_window = dsp.screen().root
# get various atoms
UTF8_STRING = dsp.get_atom( 'UTF8_STRING' ) # property type utf-8
STRING = dsp.get_atom( 'STRING' ) # property type string
NET_WM_NAME = dsp.get_atom( '_NET_WM_NAME' ) # utf-8 encoded window name
WM_NAME = dsp.get_atom( 'WM_NAME' ) # legacy ascii encoded window name
# define regex pattern to use for window name matching
src_pattern = r"/.+/"
# define replacement string
replacement = "/.../"
# length limit, replace window name only if longer than limit
limit = 16
# repeat check every 'period' seconds
period = 2
# start main loop checking all window names and
# changing them if there is a match and they are too long
while True :
# check() starts with the root window and then recursively traverses all child windows
check( root_window, src_pattern, replacement, limit )
# wait until next check
time.sleep( period )