此处使用 KDE,但可能有一个也适用于其他桌面环境的解决方案。我经常要处理很多很多窗口。大多数窗口包含许多选项卡(例如,带有许多选项卡的 Dolphin 窗口,或 Firefox、Konsole 等)。窗口标题将根据我当前的选项卡进行更改(这在大多数情况下都是有用的),但是当使用如此多的窗口时,我想对它们进行一些组织并能够手动重命名窗口,覆盖应用程序给出的窗口标题。我可能会将一个 Firefox 窗口命名为“研究”,将另一个 Firefox 窗口命名为“文档”,以便能够轻松区分我用来相应组织和分组不同选项卡的窗口。
理想情况下,我能够单击窗口标题栏并轻松为其指定自定义名称,但只要它有效,我会选择稍微麻烦一点的解决方案。
我已经尝试过wmctrl -r :SELECT: -T "Research"
,但这只是暂时有效(当应用程序更改标题时,例如切换选项卡时,标题会恢复)。
答案1
我遇到了同样的问题。
所以我编写了一个绑定到热键的 shell 脚本。
当我按下热键时,它会获取当前活动窗口(具有焦点的窗口)的窗口 ID。
然后它会给您一个弹出对话框,您可以在其中输入您希望该窗口具有的标题。
然后,每次该窗口更改名称时,它都会将其更改回您想要的标题。
要使用该脚本,您需要:
shell (我用fish而不是bash写的
fish
,
因为bash让我头疼)kdialog
将脚本绑定到热键的某种方法
(我使用xbindkeys
,因为要让它工作我所要做的就是添加:
"[PATH TO SCRIPT]/[NAME OF SCRIPT]" Mod4 + t
(即,window 键 + t)
到 my /home/o1/.xbindkeysrc
)
谢谢这家伙,谁给了我有关神奇 xprop 的信息。
(就像一年前,然后直到今天我才开始写剧本。xD)
PS 如果任何新手找到这个答案并且不知道如何使用它,请问我,我会引导您完成它。 ^^
-t
编辑:我更新了它,以便您可以通过fortitle_i_want
和-w
for开关从命令行使用它window_id
。
这是脚本:
#!/usr/local/bin/fish
# this block is so you can use it from the command line with -t and -w
if test "$argv" != "" -a (math (count $argv)%2 == 0)
for i in (seq 1 (count $argv))
if test $argv[$i] = '-t'
set title_i_want $argv[(math 1 + $i)]
else if test $argv[$i] = '-w'
set window_id $argv[(math 1 + $i)]
end
end
if not test $window_id
echo "YOU DIDN'T ENTER A `window_id` WITH `-w`,
SO MAKE SURE THE WINDOW YOU WANT HAS FOCUS
TWO SECONDS FROM NOW!"
sleep 2
end
end
# get the id of the currently focused window
if not test $window_id
set window_id (xprop -root _NET_ACTIVE_WINDOW | grep -P -o "0x\w+")
end
# get the title to force on that window
if not test $title_i_want
set title_i_want (kdialog --title "entitled" --inputbox "type the title you want and hit enter.
to stop renaming,
just enter nothing and hit esc")
end
# this bit is needed for a kludge that allows window renaming
set has_renamed_before "FALSE"
set interrupt_message "WAIT WAIT I WANT A TURN BLOO BLOO BLEE BLUH BLOO" # hopefully i never want to actually use that as a title xD
xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME $interrupt_message -id $window_id
# take the output of xprop
# pipe it into a while loop
# everytime it outputs a new line
# stuff it into a variable named "current_title"
xprop -spy _NET_WM_NAME -id $window_id | while read current_title
# cut off extraneous not-the-title bits of that string
set current_title (echo $current_title | grep -P -o '(?<=_NET_WM_NAME\(UTF8_STRING\) = ").*(?="\z)')
# if the current title is the interrupt message
# AND
# this script has renamed the window at least once before
# then we wanna let the new name take over
if test $current_title = $interrupt_message -a $has_renamed_before = "TRUE"
exit
# if title_i_want is an empty string, exit
else if test $title_i_want = ""
xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME "WIDNOW WILL START RENAMING ITSELF AS NORMAL" -id $window_id
exit
# otherwise just change the title to what i want
else if test $current_title != $title_i_want
xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME "$title_i_want" -id $window_id
set has_renamed_before "TRUE"
end
end
编辑:实际上我不再使用这个 Fish 脚本了;
我用 Ruby 重写了它:
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'trollop'
opts = Trollop.options do
opt :title_i_want, "title_i_want", default: ""
opt :bluh, "write to bluh", default: nil
opt :copy_title, "copy_title", default: nil
# TODO - AUTO OPTION
opt :auto, "auto", default: nil
end
title_i_want = opts[:title_i_want]
def get_current_wid
`xprop -root _NET_ACTIVE_WINDOW`[/0x\w+/]
end
def with_current_title wid, &block
IO.popen("xprop -spy _NET_WM_NAME _NET_WM_ICON_NAME -id #{wid}") do |io|
loop do
line = io.gets
exit if line.nil?
line = line.strip
# cut off extraneous not-the-title bits of that string
current_title = line[/(?:_NET_WM_(?:ICON_)?NAME\(UTF8_STRING\) = ")(.*)("$)/, 1]
block.call current_title unless current_title.nil?
end
end
end
def get_current_title wid
IO.popen("xprop _NET_WM_NAME _NET_WM_ICON_NAME -id #{wid}") do |io|
line = io.gets.strip
# cut off extraneous not-the-title bits of that string
current_title = line[/(?:_NET_WM_(?:ICON_)?NAME\(UTF8_STRING\) = ")(.*)("$)/, 1]
return current_title unless current_title.nil?
end
end
if opts[:copy_title]
# require "muflax"
p 1
wid = get_current_wid
`echo -n '#{get_current_title wid}(WID: #{wid})'|xclip -selection c`
exit
end
if opts[:bluh]
require "muflax"
loop do
# p 1 #db
wid = get_current_wid
# p 2 #db
File.open "bluh", "a+" do |f| f.puts get_current_title wid end
while wid == get_current_wid
# puts "..." #db
sleep 1
end
end
exit
end
#> 1A - from terminal - give title_i_want
if not title_i_want.empty?
#> 1A.1 - get current wid - assume it's the terminal_wid
terminal_wid = get_current_wid
#> 1A.2 - wait for wid to change
while get_current_wid == terminal_wid
puts "focus the window you want to title «#{title_i_want}»..."
sleep 1
end
#> 1A.3 - set new wid to target TWID
TWID = get_current_wid
#> 1B - from hotkey (or just sleeping) - no give title_i_want
else
#> 1B.1 - set current wid to target TWID
TWID = get_current_wid
#> 1B.2 - get title_i_want (with kdialog)
#> 1B.2.1 - default to current title
with_current_title TWID do |current_title|
# v :current_title #db
default_title = current_title
sublime_match = /
(?<beginning>.*?) # beginning might be...
# path
# untitled, find results, other useless junk
#
答案2
你正在寻找的听起来像窗口标记设施。我怀疑 KDE 是否支持这一点,其他 WM(例如X莫纳德或 DWM 等)。
因此,实现生产率提升的一种可能性是以旧换新kwin
XMonad和配置 XMonad 进行标记。第二个链接中描述的 XMonad 标记机制将绑定一个组合键来打开一个提示,让您标记焦点窗口。 (XMonad 的配置实际上是一个 Haskell 程序,因此请随时在 #xmonad 中寻求帮助。
编辑:虽然我建议每个人至少尝试一下平铺 WM,但我忘记指出,虽然 XMonad 通常被称为平铺 WM,但它有一个“简单浮动”模式。当然还有其他 WM 支持标记和非平铺布局,但我不知道它们与 KDE 的互操作性。
答案3
由于无法将窗口标题设置为写保护,因此该问题将无法解决,因为正如您已经发现的那样,许多程序会根据不同的操作重置其标题。
但对于 KDE 和 Gnome 用户来说也许是一个很好的建议;-)
答案4
如果您可以从脚本启动要重新命名的窗口(然后您可以为其创建菜单项),那么这里有一个简单的版本。该脚本根据启动程序的 PID 来识别窗口。它每 2 秒重置一次标题,并在无法从 PID 获取窗口 ID 时退出。它以 vlc 为例。
#!/bin/bash
vlc &
VLCPID=$!
sleep 1 # Wait for VLC to build its window
while [ /bin/true ]
do
WINDOW_ID=$(wmctrl -l -p | awk -v vpid=$VLCPID '$3 == vpid{ print $1 }')
if [ -z ${WINDOW_ID} ]; then
echo "No window ID found. Exiting."
exit
fi
wmctrl -i -r ${WINDOW_ID} -N "new window title"
sleep 2
done